Get Online Image Sizes - Avoid Memory Errors?

I get some images from a web page at the specified URL, I want to get their height and width. I am 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 problem is that the image file can be very large,

Is there anything I can do? those. specify only for images if they are less than 1 MB? or is there a better alternative approach to getting image size from a web page?

thanks

+4
source share
4 answers

Some (all?) Image formats include the width and height property in the file header. You can simply request enough bytes to read the header and then parse them yourself. You can add a range header to your web request that will only request the first 50 bytes (50 is just an example, which you probably need less) image file with:

 wReq.AddRange(0, 50); 

I assume that this will work only if you know that the formats you work with include this data.

Edit: Looks like I didn't understand the AddRange method AddRange . This is now fixed. I also went ahead and checked it, getting the width and height of the 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(); } 
+5
source

You only need to load the header from the image file to find the image size, see ....

BMP: (only 26 bytes required) http://www.fileformat.info/format/bmp/corion.htm

JPG: (scan for the Star Frame marker) http://wiki.tcl.tk/757

GIF: (10 bytes needed, i.e. the first two words of the 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 is (don't rely on the file name extension. For example, bmp can be called ".gif" on. Once you know the file type, you look at the specification to find out which offset to read.

PS Take a hex editor, for example, "Hex Editor XVI32" to see the file structure. You can download XVI32 here: http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm

+3
source

You might want to write a web service that specifies the name of the input image, and specify the size as the answer.

Based on the value obtained, you can upload an image.

If you want something easier than a web service, go for the HTTP handler.

+1
source

You can try using the FileInfo class to find the file size.

 long fileSizeInKb = new FileInfo(fileName).Length / 1000; if (fileSizeInKb < 1000) { // get image } 

The Length property returns the number of bytes in the current file.

0
source

Source: https://habr.com/ru/post/1334595/


All Articles