我正在从一个并不总是包含内容类型的服务下载一些图像,并且没有为我正在下载的文件提供扩展名(呃,不要问).
在.NET中确定图像格式的最佳方法是什么?
正在读取这些下载图像的应用程序需要具有适当的文件扩展名或者所有地狱都会松动.
一个可能更简单的方法是使用Image.FromFile()然后使用RawFormat属性,因为它已经知道最常见格式的标头中的魔术位,如下所示:
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
您可以使用下面的代码而不参考System.Drawing和不必要的对象Image创建.即使没有System.IO的流和引用,您也可以使用Alex解决方案.
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; }
所有图像格式都将其初始字节设置为特定值:
JPG:0xFF 0xD8
PNG:0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A
GIF:'G''我''F'
搜索"jpg文件格式",用您需要识别的其他文件格式替换jpg.
正如Garth建议的那样,有一个这样的"魔术数字"数据库显示了许多文件的文件类型.如果您必须检测许多不同的文件类型,那么值得查看它以查找所需的信息.如果您确实需要对此进行扩展以涵盖许多文件类型,请查看实现引擎的关联文件命令以正确使用数据库(对于许多文件格式而言,它是非常简单的,几乎是一个统计过程)
-亚当
亚当正指向正确的方向.
如果您想了解如何检测几乎所有文件,请在file
UNIX,Linux或Mac OS X计算机上查看命令背后的数据库.
file
使用"神奇数字"数据库 - 亚当列出的那些初始字节 - 来感知文件的类型.man file
会告诉你在哪里可以找到你机器上的数据库,例如/usr/share/file/magic
.man magic
会告诉你它的格式.
您可以根据您在数据库中看到的内容编写自己的检测代码,使用预打包的库(例如python-magic),或者 - 如果您真的喜欢冒险 - 实现.NET版本libmagic
.我找不到一个,希望其他成员可以指出一个.
如果您没有方便的UNIX机器,数据库将如下所示:
# PNG [Portable Network Graphics, or "PNG's Not GIF"] images # (Greg Roelofs, newt@uchicago.edu) # (Albert Cahalan, acahalan@cs.uml.edu) # # 137 P N G \r \n ^Z \n [4-byte length] H E A D [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
祝好运!