在 C# 中,判断特定文件是否是图像的最佳方法是什么?
大多数图片格式在图像的前几个字节中指定文件类型。您可以读取几个字节并查找正确的标头。
从技术上讲,文件扩展名不保存有关图像的任何重要数据。它只是帮助操作系统确定使用什么程序来打开它。 (但是,检查 extn 可能是最简单的方法,而且通常是正确的。)
这尚未经过测试,但它是这样的:
private string MimeType (string Filename)
{
string mime = "[default]";
string ext = GetExtension(Filename).ToLower();
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(ext);
if (rk != null && rk.GetValue("Content Type") != null)
mime = rk.GetValue("Content Type").ToString();
return mime;
}
(抱歉,我已经有一段时间没做注册表了。)
我们这样做的方式(我现在找不到确切的代码,因此以下内容未经测试)是尝试将图像加载为位图。如果失败,它就不是图像
bool isImage;
try
{
Bitmap.FromFile(filePath);
isImage = true;
}
catch
{
isImage = false;
}
我认为除了尝试加载和显示图像之外,没有任何方法可以保证给定文件(或任何字节集)一定代表图像。
但是,如果您有一些神秘字节,您可以随时检查某些字节签名,以尝试推断它是否是格式良好的图像文件。您可以在维基百科上查找文件头,但这里有一些我在单元测试中使用的代码来验证第三方报告工具的输出:
// Some signatures:
const string _pdfSignature = "%PDF-";
readonly byte[] _bmpSignature = new byte[2] { 0x42, 0x4D };
readonly byte[] _pngSignature = new byte[8] {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
readonly byte[] _gifSignature = new byte[6] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 };
对于 JPG:
Assert.That(_theBytes[0] == 0xFF && _theBytes[1] == 0xD8); //Start of jpg file
Assert.That(_theBytes[_theBytes.Length - 2] == 0xFF && _theBytes[_theBytes.Length - 1] == 0xD9); //End of jpg file
大多数图像文件在文件的开头都有一个或两个魔术字节。解码器和图像查看器使用它来识别文件类型。没有任何一条规则可以帮助您。
如果您需要验证文件是否是有效的图像格式,那么您将必须使用某种代码尝试根据您期望的文件类型来解析内容。为此,您可以调用 Image 类上的静态 FromFile 方法来尝试获取 Image 实例。
您可以检查前几个字节以查看特定图像格式的标记是否存在,但就像检查文件扩展名一样,它不能保证内容是有效的图像格式。
如果您不需要验证,检查文件扩展名或 mime 类型就可以了。
检查文件扩展名
诚然,我对此没有做太多,但这不是简单地查找哑剧类型吗?