Im getting some images from a webpage at a specified url, i want to get their heights and widths. I'm using something like this:
Stream str = null;
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(ImageUrl);
HttpWebResponse wRes = (HttpWebResponse)(wReq).GetResponse();
str = wRes.GetResponseStream();
var imageOrig = System.Drawing.Image.FromStream(str);
int height = imageOrig.Height;
int width = imageOrig.Width;
My main concern with this is that that the image file may actually be very large,
Is there anything I can do? ie specify to only get images if they are less than 1mb? or is there a better alternative approach to getting the dimension of an image from a webpage?
thanks
Some (all?) image formats include the width and height property in the header of the file. You could just request enough bytes to be able to read the header and then parse them yourself. You can add a range header to your web request that will request only the first 50 bytes (50 is just an example, you'd probably need less) of the image file with:
wReq.AddRange(0, 50);
I suppose this will only work if you know that the formats you are working with include this data.
Edit: Looks like I misunderstood the AddRange
method before. It's fixed now. I also went ahead and tested it out by getting the width and height of a png using this documentation.
static void Main(string[] args)
{
string imageUrl = "http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png";
byte[] pngSignature = new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 };
HttpWebRequest wReq = (HttpWebRequest)WebRequest.Create(imageUrl);
wReq.AddRange(0, 30);
WebResponse wRes = wReq.GetResponse();
byte[] buffer = new byte[30];
int width = 0;
int height = 0;
using (Stream stream = wRes.GetResponseStream())
{
stream.Read(buffer, 0, 30);
}
// Check for Png
// 8 byte - Signature
// 4 byte - Chunk length
// 4 byte - Chunk type - IDHR (Image Header)
// 4 byte - Width
// 4 byte - Height
// Other stuff we don't care about
if (buffer.Take(8).SequenceEqual(pngSignature))
{
var idhr = buffer.Skip(12);
width = BitConverter.ToInt32(idhr.Skip(4).Take(4).Reverse().ToArray(), 0);
height = BitConverter.ToInt32(idhr.Skip(8).Take(4).Reverse().ToArray(), 0);
}
// Check for Jpg
//else if (buffer.Take(?).SequenceEqual(jpgSignature))
//{
// // Do Jpg stuff
//}
// Check for Gif
//else if (etc...
Console.WriteLine("Width: " + width);
Console.WriteLine("Height: " + height);
Console.ReadKey();
}
You only need to download the header from a graphics file in order to find the picture size, see...
BMP: (only 26 bytes needed) http://www.fileformat.info/format/bmp/corion.htm
JPG: (scan for "Star of Frame" marker) http://wiki.tcl.tk/757
GIF: (10 bytes needed, i.e. first two words of Logical Screen Descriptor) http://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp
also, notice how you can read the first couple of bytes to find out what the file-type really is (don't rely on the extension of the filename. For example, a bmp could be named ".gif" by accident. Once you know the filetype you look at the spec to know what offset to read.
P.S. get yourself a hex editor, such as "Hex Editor XVI32", to see the file structure. You can download XVI32 here: http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With