<p>I'm downloading some images from a service that doesn't always include a content-type and doesn't provide an extension for the file I'm downloading (ugh, don't ask).</p>

<p>What's the best way to determine the image format in .NET?</p>

<p>The application that is reading these downloaded images needs to have a proper file extension or all hell breaks loose.</p>

[{'answer_id': 55873, 'author': 'Ash', 'author_id': 5023, 'author_profile': 'https://Stackoverflow.com/users/5023', 'pm_score': 0, 'selected': False, 'text': '<p>Try loading the stream into a System.IO.BinaryReader.  </p>\n\n<p>Then you will need to refer to the specifications for each image format you need, and load the header byte by byte to compare against the specifications.  For example here are the <a href="http://www.libpng.org/pub/png/pngdocs.html" rel="nofollow noreferrer">PNG specifications</a></p>\n\n<p>Added:  The actual <a href="http://www.libpng.org/pub/png/spec/1.2/PNG-Structure.html" rel="nofollow noreferrer">file structure</a> for PNG.</p>\n'}, {'answer_id': 55876, 'author': 'Adam Davis', 'author_id': 2915, 'author_profile': 'https://Stackoverflow.com/users/2915', 'pm_score': 5, 'selected': False, 'text': '<p>All the image formats set their initial bytes to a particular value:</p>\n\n<ul>\n<li>JPG: <a href="http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure" rel="noreferrer">0xFF 0xD8</a></li>\n<li>PNG: <a href="http://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header" rel="noreferrer">0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A</a></li>\n<li>GIF: <a href="http://www.w3.org/Graphics/GIF/spec-gif89a.txt" rel="noreferrer">\'G\' \'I\' \'F\'</a></li>\n</ul>\n\n<p>Search for "jpg file format" replacing jpg with the other file formats you need to identify.</p>\n\n<p>As Garth recommends, there is a <a href="http://pwet.fr/man/linux/formats/magic" rel="noreferrer">database of such \'magic numbers\'</a> showing the file type of many files.  If you have to detect a lot of different file types it\'s worthwhile looking through it to find the information you need.  If you do need to extend this to cover many, many file types, look at the associated <a href="http://pwet.fr/man/linux/commandes/posix/file" rel="noreferrer">file command</a> which implements the engine to use the database correctly (it\'s non trivial for many file formats, and is almost a statistical process)</p>\n\n<p>-Adam</p>\n'}, {'answer_id': 55879, 'author': 'Garth Kidd', 'author_id': 5700, 'author_profile': 'https://Stackoverflow.com/users/5700', 'pm_score': 3, 'selected': False, 'text': '<p>Adam is pointing in exactly the right direction. </p>\n\n<p>If you want to find out how to <strong>sense almost any file</strong>, look at the database behind the <code>file</code> command on a UNIX, Linux, or Mac OS X machine. </p>\n\n<p><code>file</code> uses a database of “magic numbers” — those initial bytes Adam listed — to sense a file\'s type. <code>man file</code> will tell you where to find the database on your machine, e.g. <code>/usr/share/file/magic</code>. <code>man magic</code> will tell you its <a href="http://linux.die.net/man/5/magic" rel="noreferrer">format</a>. </p>\n\n<p>You can either write your own detection code based on what you see in the database, use pre-packaged libraries (e.g. <a href="http://hupp.org/adam/hg/python-magic" rel="noreferrer">python-magic</a>), or — if you\'re <em>really</em> adventurous — implement a .NET version of <code>libmagic</code>. I couldn\'t find one, and hope another member can point one out. </p>\n\n<p>In case you don\'t have a UNIX machine handy, the database looks like this:</p>\n\n<pre>\n# PNG [Portable Network Graphics, or "PNG\'s Not GIF"] images\n# (Greg Roelofs, newt@uchicago.edu)\n# (Albert Cahalan, acahalan@cs.uml.edu)\n#\n# 137 P N G \\r \\n ^Z \\n [4-byte length] H E A D [HEAD data] [HEAD crc] ...\n#\n0       string          \\x89PNG         PNG image data,\n>4      belong          !0x0d0a1a0a     CORRUPTED,\n>4      belong          0x0d0a1a0a\n>>16    belong          x               %ld x\n>>20    belong          x               %ld,\n>>24    byte            x               %d-bit\n>>25    byte            0               grayscale,\n>>25    byte            2               \\b/color RGB,\n>>25    byte            3               colormap,\n>>25    byte            4               gray+alpha,\n>>25    byte            6               \\b/color RGBA,\n#>>26   byte            0               deflate/32K,\n>>28    byte            0               non-interlaced\n>>28    byte            1               interlaced\n1       string          PNG             PNG image data, CORRUPTED\n\n# GIF\n0       string          GIF8            GIF image data\n>4      string          7a              \\b, version 8%s,\n>4      string          9a              \\b, version 8%s,\n>6      leshort         >0              %hd x\n>8      leshort         >0              %hd\n#>10    byte            &0x80           color mapped,\n#>10    byte&0x07       =0x00           2 colors\n#>10    byte&0x07       =0x01           4 colors\n#>10    byte&0x07       =0x02           8 colors\n#>10    byte&0x07       =0x03           16 colors\n#>10    byte&0x07       =0x04           32 colors\n#>10    byte&0x07       =0x05           64 colors\n#>10    byte&0x07       =0x06           128 colors\n#>10    byte&0x07       =0x07           256 colors\n</pre>\n\n<p>Good luck!</p>\n'}, {'answer_id': 55887, 'author': 'Vinko Vrsalovic', 'author_id': 5190, 'author_profile': 'https://Stackoverflow.com/users/5190', 'pm_score': 7, 'selected': True, 'text': '<p>A probably easier approach would be to use Image.FromFile() and then use the RawFormat property, as it already knows about the magic bits in the headers for the most common formats, like this:</p>\n\n<pre><code>Image i = Image.FromFile("c:\\\\foo");\nif (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat)) \n    MessageBox.Show("JPEG");\nelse if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat))\n    MessageBox.Show("GIF");\n//Same for the rest of the formats\n</code></pre>\n'}, {'answer_id': 12051761, 'author': 'slobodans', 'author_id': 946580, 'author_profile': 'https://Stackoverflow.com/users/946580', 'pm_score': 2, 'selected': False, 'text': '<p>There is programmatic way to determine image MIMETYPE.</p>\n\n<p>There is class <strong>System.Drawing.Imaging.ImageCodecInfo</strong>. </p>\n\n<p>This class have properties <strong>MimeType</strong> and <strong>FormatID</strong>. Also it have a method <strong>GetImageEncoders</strong> which return collection of all image encoders. \nIt is easy to create Dictionary of mime types indexed by format id.</p>\n\n<p>Class <strong>System.Drawing.Image</strong> have property <strong>RawFormat</strong> of Type <strong>System.Drawing.Imaging.ImageFormat</strong> which have property <strong>Guid</strong> which is equivalent of the property <strong>FormatID</strong> of class <strong>System.Drawing.Imaging.ImageCodecInfo</strong>, and that is key to take MIMETYPE from dictionary.</p>\n\n<p>Example:</p>\n\n<p>Static method to create dictionary of mime types</p>\n\n<pre><code>static Dictionary&lt;Guid, string&gt; GetImageFormatMimeTypeIndex()\n{\n  Dictionary&lt;Guid, string&gt; ret = new Dictionary&lt;Guid, string&gt;();\n\n  var encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders();\n\n  foreach(var e in encoders)\n  {\n    ret.Add(e.FormatID, e.MimeType);\n  }\n\n  return ret;\n}\n</code></pre>\n\n<p>Use:</p>\n\n<pre><code>Dictionary&lt;Guid, string&gt; mimeTypeIndex = GetImageFormatMimeTypeIndex();\n\nFileStream imgStream = File.OpenRead(path);\nvar image = System.Drawing.Image.FromStream(imgStream);\nstring mimeType = mimeTypeIndex[image.RawFormat.Guid];\n</code></pre>\n'}, {'answer_id': 12451102, 'author': 'Ivan Kochurkin', 'author_id': 1046374, 'author_profile': 'https://Stackoverflow.com/users/1046374', 'pm_score': 5, 'selected': False, 'text': '<p>You can use code below without reference of System.Drawing and unnecessary creation of object Image. Also you can use <a href="https://stackoverflow.com/a/9446083/1046374">Alex</a> solution even without stream and reference of System.IO.</p>\n\n<pre><code>public enum ImageFormat\n{\n    bmp,\n    jpeg,\n    gif,\n    tiff,\n    png,\n    unknown\n}\n\npublic static ImageFormat GetImageFormat(Stream stream)\n{\n    // see http://www.mikekunz.com/image_file_header.html\n    var bmp = Encoding.ASCII.GetBytes("BM");     // BMP\n    var gif = Encoding.ASCII.GetBytes("GIF");    // GIF\n    var png = new byte[] { 137, 80, 78, 71 };    // PNG\n    var tiff = new byte[] { 73, 73, 42 };         // TIFF\n    var tiff2 = new byte[] { 77, 77, 42 };         // TIFF\n    var jpeg = new byte[] { 255, 216, 255, 224 }; // jpeg\n    var jpeg2 = new byte[] { 255, 216, 255, 225 }; // jpeg canon\n\n    var buffer = new byte[4];\n    stream.Read(buffer, 0, buffer.Length);\n\n    if (bmp.SequenceEqual(buffer.Take(bmp.Length)))\n        return ImageFormat.bmp;\n\n    if (gif.SequenceEqual(buffer.Take(gif.Length)))\n        return ImageFormat.gif;\n\n    if (png.SequenceEqual(buffer.Take(png.Length)))\n        return ImageFormat.png;\n\n    if (tiff.SequenceEqual(buffer.Take(tiff.Length)))\n        return ImageFormat.tiff;\n\n    if (tiff2.SequenceEqual(buffer.Take(tiff2.Length)))\n        return ImageFormat.tiff;\n\n    if (jpeg.SequenceEqual(buffer.Take(jpeg.Length)))\n        return ImageFormat.jpeg;\n\n    if (jpeg2.SequenceEqual(buffer.Take(jpeg2.Length)))\n        return ImageFormat.jpeg;\n\n    return ImageFormat.unknown;\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/55869', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/5277/']