Getting image dimensions without reading the entire file?

Your best bet as always is to find a well tested library. However, you said that is difficult, so here is some dodgy largely untested code that should work for a fair number of cases.

Your best bet as always is to find a well tested library. However, you said that is difficult, so here is some dodgy largely untested code that should work for a fair number of cases: using System; using System.Collections. Generic; using System.

Drawing; using System. IO; using System. Linq; namespace ImageDimensions { public static class ImageHelper { const string errorMessage = "Could not recognise image format."; private static Dictionary> imageFormatDecoders = new Dictionary>() { { new byte{ 0x42, 0x4D }, DecodeBitmap}, { new byte{ 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif }, { new byte{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif }, { new byte{ 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng }, { new byte{ 0xff, 0xd8 }, DecodeJfif }, }; /// /// Gets the dimensions of an image.

/// /// The path of the image to get the dimensions of. /// The dimensions of the specified image. /// The image was of an unrecognised format.

Public static Size GetDimensions(string path) { using (BinaryReader binaryReader = new BinaryReader(File. OpenRead(path))) { try { return GetDimensions(binaryReader); } catch (ArgumentException e) { if (e.Message. StartsWith(errorMessage)) { throw new ArgumentException(errorMessage, "path", e); } else { throw e; } } } } /// /// Gets the dimensions of an image.

/// /// The path of the image to get the dimensions of. /// The dimensions of the specified image. /// The image was of an unrecognised format.

Public static Size GetDimensions(BinaryReader binaryReader) { int maxMagicBytesLength = imageFormatDecoders.Keys. OrderByDescending(x => x. Length).First().

Length; byte magicBytes = new bytemaxMagicBytesLength; for (int I = 0; I Key)) { return kvPair. Value(binaryReader); } } } throw new ArgumentException(errorMessage, "binaryReader"); } private static bool StartsWith(this byte thisBytes, byte thatBytes) { for(int I = 0; I = thatBytesi) { return false; } } return true; } private static short ReadLittleEndianInt16(this BinaryReader binaryReader) { byte bytes = new bytesizeof(short); for (int I = 0; I ReadBytes(16); int width = binaryReader. ReadInt32(); int height = binaryReader.

ReadInt32(); return new Size(width, height); } private static Size DecodeGif(BinaryReader binaryReader) { int width = binaryReader. ReadInt16(); int height = binaryReader. ReadInt16(); return new Size(width, height); } private static Size DecodePng(BinaryReader binaryReader) { binaryReader.

ReadBytes(8); int width = binaryReader. ReadLittleEndianInt32(); int height = binaryReader. ReadLittleEndianInt32(); return new Size(width, height); } private static Size DecodeJfif(BinaryReader binaryReader) { while (binaryReader.ReadByte() == 0xff) { byte marker = binaryReader.ReadByte(); short chunkLength = binaryReader.

ReadLittleEndianInt16(); if (marker == 0xc0) { binaryReader.ReadByte(); int height = binaryReader. ReadLittleEndianInt16(); int width = binaryReader. ReadLittleEndianInt16(); return new Size(width, height); } binaryReader.

ReadBytes(chunkLength - 2); } throw new ArgumentException(errorMessage); } } } Hopefully the code is fairly obvious.To add a new file format you add it to imageFormatDecoders with the key being an array of the "magic bits" which appear at the begining of every file of the given format and the value being a function which extracts the size from the stream. Most formats are simple enough, the only real stinker is jpeg.

1 Agreed, JPEG sucks. Btw - a note for the people who want to use this code in the future: this is indeed untested. I've gone through it with a fine comb, and here's what I found: BMP format has another (ancient) header variation where dimensions are 16-bit; plus height can be negative (drop the sign then).

As for JPEG - 0xC0 isn't the only header. Basically all of 0xC0 to 0xCF except 0xC4 and 0xCC are valid headers (you can easily get them in interlaced JPGs). And, to make things more fun, height can be 0 and specified later in a 0xDC block.

See w3. Org/Graphics/JPEG/itu-t81. Pdf – Vilx- Feb 22 at 12:36.

System.Windows.Media.Imaging. BitmapDecoder, etc.? I believe some effort was into making sure those codecs only read a subset of the file in order to determine header information. It's worth a check.

Thank you. It seems reasonable, but my hosting has . NET 2.

– Jan Zich Sep 21 '08 at 16:50 Excellent answer. If you can get a reference to PresentationCore in your project, this is the way to go. – ojrac Jan 11 '10 at 17:18.

I was looking for something similar a few months earlier. I wanted to read the type, version, height and width of a GIF image but couldn’t find anything useful online. Fortunately in case of GIF, all this information is easy to get hold of: Type: Bytes 1-3 Version: Bytes 4-7 Height: Bytes 8-9 Width: Bytes 10-11 PNG are slightly more complex, width and height are 4-bytes each and are located at bytes 16-19 and 20-23 respectively.As mentioned above wotsit is a good site for detailed specs on image and data formats, however, the PNG specs at pnglib are much more detailed.

Here’s my original code for checking GIFs, I have also slapped together something for PNGs, hope it will be useful after cleanup. Warning: ugly, undocumented code public class ImageSizeTest { public static void Main() { // For Gifs FileStream f = new FileStream("iProduct. Gif", FileMode.

Open, FileAccess. Read); displayGifInfo(f); f.Close(); f = null; Console. WriteLine(""); // For Pngs f = new FileStream("WaveletsGamma.

Png", FileMode. Open, FileAccess. Read); displayPngInfo(f); f.Close(); f = null; } public static void displayGifInfo(FileStream f) { string type = ((char)f.ReadByte()).ToString(); type += ((char)f.ReadByte()).ToString(); type += ((char)f.ReadByte()).ToString(); string version = ((char)f.ReadByte()).ToString(); version += ((char)f.ReadByte()).ToString(); version += ((char)f.ReadByte()).ToString(); int lower = f.ReadByte(); int upper = f.ReadByte(); int width = lower | upper WriteLine("PNG\nWidth: " + width + "\nHeight: " + height); } }.

Based on the answers so far and some additional searching, it seems that in the . NET 2 class library there is no functionality for it. So I decided to write my own.

Here is a very rough version of it. At the moment, I needed it only for JPG’s. So it completes the answer posted by Abbas.

There is no error checking or any other verification, but I currently need it for a limited task, and it can be eventually easily added. I tested it on some number of images, and it usually does not read more that 6K from an image. I guess it depends on the amount of the EXIF data.

Using System; using System. IO; namespace Test { class Program { static bool GetJpegDimension( string fileName, out int width, out int height) { width = height = 0; bool found = false; bool eof = false; FileStream stream = new FileStream( fileName, FileMode. Open, FileAccess.

Read); BinaryReader reader = new BinaryReader(stream); while (!found || eof) { // read 0xFF and the type reader.ReadByte(); byte type = reader.ReadByte(); // get length int len = 0; switch (type) { // start and end of the image case 0xD8: case 0xD9: len = 0; break; // restart interval case 0xDD: len = 2; break; // the next two bytes is the length default: int lenReadByte(); int lenLo = reader.ReadByte(); len = (len 0) { // read the data byte data = reader. ReadBytes(len); // this is what we are looking for if (type == 0xC0) { width = data1 WriteLine(file + ": " + w + " x " + h); } } } }.

It's going to depend on the file format. Usually they will state it up in the early bytes of the file. And, usually, a good image-reading implementation will take that into account.

I can't point you to one for . NET though.

Yes, you can absolutely do this and the code depends on the file format. I work for an imaging vendor (Atalasoft), and our product provides a GetImageInfo() for every codec that does the minimum to find out dimensions and some other easy to get data. If you want to roll your own, I suggest starting with wotsit.Org, which has detailed specs for pretty much all image formats and you will see how to identify the file and also where information in it can be found.

If you are comfortable working with C, then the free jpeglib can be used to get this information too. I would bet that you can do this with . NET libraries, but I don't know how.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions