Define image file type

I am downloading some images from a service that does not always include the content type and does not provide an extension for the file that I am uploading (ugh, don't ask).

What is the best way to determine image format in .NET?

An application that reads these downloaded images must have the correct file extension, or all hell breaks.

+41
content-type mime-types image
Sep 11 '08 at 5:50
source share
6 answers

Most likely, it is easier to use Image.FromFile () and then use the RawFormat property, since it already knows about the magic bits in the headers for the most common formats, for example:

Image i = Image.FromFile("c:\\foo"); if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat)) MessageBox.Show("JPEG"); else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat)) MessageBox.Show("GIF"); //Same for the rest of the formats 
+50
Sep 11 '08 at 6:11
source share

All image formats set the initial bytes to a specific value:

Find "jpg file format" by replacing jpg with other file formats that you need to identify.

As Garth recommends, there is a database of such "magic numbers" that indicate the file type of many files. If you need to find many different types of files, you should look at it to find the information you need. If you need to expand this to cover many, many types of files, look at the associated file command , which implements a mechanism for working correctly with the database (it is not trivial for many file formats and is an almost statistical process)

-Adam

+21
Sep 11 '08 at 5:57
source share

You can use the code below without reference to System.Drawing and unnecessarily creating an Image object. You can also use Alex even without a stream and a System.IO link.

 public enum ImageFormat { bmp, jpeg, gif, tiff, png, unknown } public static ImageFormat GetImageFormat(Stream stream) { // see http://www.mikekunz.com/image_file_header.html var bmp = Encoding.ASCII.GetBytes("BM"); // BMP var gif = Encoding.ASCII.GetBytes("GIF"); // GIF var png = new byte[] { 137, 80, 78, 71 }; // PNG var tiff = new byte[] { 73, 73, 42 }; // TIFF var tiff2 = new byte[] { 77, 77, 42 }; // TIFF var jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg var jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg canon var buffer = new byte[4]; stream.Read(buffer, 0, buffer.Length); if (bmp.SequenceEqual(buffer.Take(bmp.Length))) return ImageFormat.bmp; if (gif.SequenceEqual(buffer.Take(gif.Length))) return ImageFormat.gif; if (png.SequenceEqual(buffer.Take(png.Length))) return ImageFormat.png; if (tiff.SequenceEqual(buffer.Take(tiff.Length))) return ImageFormat.tiff; if (tiff2.SequenceEqual(buffer.Take(tiff2.Length))) return ImageFormat.tiff; if (jpeg.SequenceEqual(buffer.Take(jpeg.Length))) return ImageFormat.jpeg; if (jpeg2.SequenceEqual(buffer.Take(jpeg2.Length))) return ImageFormat.jpeg; return ImageFormat.unknown; } 
+18
Sep 16 '12 at 10:01
source share

Adam is pointing in the right direction.

If you want to learn how to read almost any file , look at the database behind the file command on a UNIX, Linux, or Mac OS X computer.

file uses a database of β€œmagic numbers” β€”these initial bytes listed by Adam β€” to determine the type of file. man file will tell you where to find the database on your computer, for example. /usr/share/file/magic . man magic will tell you its format .

You can write your own discovery code based on what you see in the database, use pre-packaged libraries (like python-magic ), or - if you're really adventurous - implement the .NET version of libmagic . I could not find him, and I hope that another member can point to him.

If you do not have a UNIX machine, the database is as follows:

 # PNG [Portable Network Graphics, or "PNG Not GIF"] images
 # (Greg Roelofs, newt@uchicago.edu)
 # (Albert Cahalan, acahalan@cs.uml.edu)
 #
 # 137 PNG \ r \ n ^ Z \ n [4-byte length] HEAD [HEAD data] [HEAD crc] ...
 #
 0 string \ x89PNG PNG image data,
 > 4 belong! 0x0d0a1a0a CORRUPTED,
 > 4 belong 0x0d0a1a0a
 >> 16 belong x% ld x
 >> 20 belong x% ld,
 >> 24 byte x% d-bit
 >> 25 byte 0 grayscale,
 >> 25 byte 2 \ b / color RGB,
 >> 25 byte 3 colormap,
 >> 25 byte 4 gray + alpha,
 >> 25 byte 6 \ b / color RGBA,
 # >> 26 byte 0 deflate / 32K,
 >> 28 byte 0 non-interlaced
 >> 28 byte 1 interlaced
 1 string PNG PNG image data, CORRUPTED

 # GIF
 0 string GIF8 GIF image data
 > 4 string 7a \ b, version 8% s,
 > 4 string 9a \ b, version 8% s,
 > 6 leshort> 0% hd x
 > 8 leshort> 0% hd
 #> 10 byte & 0x80 color mapped,
 #> 10 byte & 0x07 = 0x00 2 colors
 #> 10 byte & 0x07 = 0x01 4 colors
 #> 10 byte & 0x07 = 0x02 8 colors
 #> 10 byte & 0x07 = 0x03 16 colors
 #> 10 byte & 0x07 = 0x04 32 colors
 #> 10 byte & 0x07 = 0x05 64 colors
 #> 10 byte & 0x07 = 0x06 128 colors
 #> 10 byte & 0x07 = 0x07 256 colors

Good luck

+8
Sep 11 '08 at 6:01
source share

There is a software method for detecting MIMETYPE images.

There is a class System.Drawing.Imaging.ImageCodecInfo .

This class has the MimeType and FormatID properties . It also has a GetImageEncoders method that returns a collection of all image encoders. It's easy to create a dictionary of mime types indexed by format identifier.

The System.Drawing.Image class has a RawFormat property of the System.Drawing.Imaging.ImageFormat type, which has a Guid property that is equivalent to the FormatID property of the System.Drawing.Imaging.ImageCodecInfo class, and this is the key to using MIMETYPE from the dictionary.

Example:

Static method for creating a mime type dictionary

 static Dictionary<Guid, string> GetImageFormatMimeTypeIndex() { Dictionary<Guid, string> ret = new Dictionary<Guid, string>(); var encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders(); foreach(var e in encoders) { ret.Add(e.FormatID, e.MimeType); } return ret; } 

Using:

 Dictionary<Guid, string> mimeTypeIndex = GetImageFormatMimeTypeIndex(); FileStream imgStream = File.OpenRead(path); var image = System.Drawing.Image.FromStream(imgStream); string mimeType = mimeTypeIndex[image.RawFormat.Guid]; 
+2
Aug 21 '12 at 9:18
source share

Try loading the stream into System.IO.BinaryReader.

Then you will need to refer to the specifications for each image format that you need and load the header byte by byte for comparison with the specifications. For example, PNG specifications

Added: Actual structure for PNG.

0
Sep 11 '08 at 5:54
source share



All Articles