C#如何测试文件是否为jpeg?

C#如何测试文件是否为jpeg?,c#,jpeg,C#,Jpeg,使用C#如何测试文件是否为jpeg?我应该检查.jpg扩展名吗 谢谢。您可以使用。您可以找到有关jpeg文件格式的文档,特别是标题信息。然后尝试从文件中读取此信息,并将其与预期的jpeg头字节进行比较。此处的代码: 演示如何获取元数据。如果你的图像不是有效的JPEG,我想这会引发一个异常。一旦你有了扩展,你可以使用正则表达式来验证它 ^.*\.(jpg|JPG)$ 以流的形式打开文件并查找JPEG格式的文件 JPEG图像文件以FF D8和 以FF D9结束。JPEG/JFIF文件 包含“JF

使用C#如何测试文件是否为jpeg?我应该检查.jpg扩展名吗


谢谢。

您可以使用。

您可以找到有关jpeg文件格式的文档,特别是标题信息。然后尝试从文件中读取此信息,并将其与预期的jpeg头字节进行比较。

此处的代码:


演示如何获取元数据。如果你的图像不是有效的JPEG,我想这会引发一个异常。

一旦你有了扩展,你可以使用正则表达式来验证它

^.*\.(jpg|JPG)$

以流的形式打开文件并查找JPEG格式的文件

JPEG图像文件以FF D8和 以FF D9结束。JPEG/JFIF文件 包含“JFIF”(4A)的ASCII码 46)作为以null结尾的字符串。 JPEG/Exif文件包含ASCII代码 对于“Exif”(45 78 69 66),也作为 以空结尾的字符串


您可以尝试将文件加载到图像中,然后检查格式

Image img = Image.FromFile(filePath);
bool isBitmap = img.RawFormat.Equals(ImageFormat.Jpeg);

或者,您可以打开文件并检查标题以获取类型,然后读取标题字节。本文包含关于几种常见图像格式的信息,包括JPEG:


检查文件扩展名是不够的,因为文件名可能存在漏洞

一种快速而肮脏的方法是尝试使用image类加载图像并捕获任何异常:

Image image = Image.FromFile(@"c:\temp\test.jpg");
这并不理想,因为您可能会得到任何类型的异常,例如OutOfMemoryException、FileNotFoundException等


最彻底的方法是将文件视为二进制文件,并确保头文件与JPG格式匹配。我确信它在某个地方被描述过。

最好的方法是尝试使用Drawing.Bitmap(string)构造函数从它创建一个图像,并查看它是否失败或引发异常。一些答案的问题是:首先,扩展完全是任意的,它可以是jpg、jpeg、jpe、bob、tim等等。其次,仅仅使用标题还不足以100%确定。它可以确定文件不是jpeg,但不能保证文件是jpeg,任意二进制文件在开始时可能具有相同的字节序列

这将遍历当前目录中的每个文件,如果找到的任何扩展名为JPG或JPEG的文件都是JPEG图像,则将输出

      foreach (FileInfo f in new DirectoryInfo(".").GetFiles())
        {
            if (f.Extension.ToUpperInvariant() == ".JPG"
                || f.Extension.ToUpperInvariant() == ".JPEG")
            {
                Image image = Image.FromFile(f.FullName);

                if (image.RawFormat == ImageFormat.Jpeg)
                {
                    Console.WriteLine(f.FullName + " is a Jpeg image");
                }
            }
        }

根据您查看此文件的上下文,您需要记住这一点

(链接到陈雷蒙的博客条目。)

几个选项:

您可以检查文件扩展名:

static bool HasJpegExtension(string filename)
{
    // add other possible extensions here
    return Path.GetExtension(filename).Equals(".jpg", StringComparison.InvariantCultureIgnoreCase)
        || Path.GetExtension(filename).Equals(".jpeg", StringComparison.InvariantCultureIgnoreCase);
}
或在文件头中检查是否正确:

static bool HasJpegHeader(string filename)
{
    using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
    {
        UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
        UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) or EXIF marker(FFE1)

        return soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
    }
}
另一个选项是加载图像并检查正确的类型。但是,这效率较低(除非您无论如何都要加载映像),但可能会为您提供最可靠的结果(请注意加载和解压缩的额外成本以及可能的异常处理):


天哪,这么多代码示例都是错的,错的

EXIF文件的标记为0xff*e1*,JFIF文件的标记为0xff*e0*。因此,所有依赖0xffe0检测JPEG文件的代码都将丢失所有EXIF文件

这是一个可以同时检测两者的版本,并且可以很容易地修改为只返回JFIF或只返回EXIF。(例如,在尝试恢复iPhone图片时非常有用)


只需获取文件的媒体类型并验证:

private bool isJpeg()
        {
string p = currFile.Headers.ContentType.MediaType;
            return p.ToLower().Equals("image/jpeg") || p.ToLower().Equals("image/pjpeg") || p.ToLower().Equals("image/png");
        }

在检查文件扩展名后,读取图像的前四个字节和图像的最后两个字节,如图所示,对值255217的最后两个字节执行此操作 对于其他文件可以这样做


也应该包括
jpeg
,并且可能会花一分钟搜索其他不太常见的jpeg文件扩展名。对于每个积极的情况,您可能会在不想的时候解码整个图像,对于每一个消极的情况,我希望你需要处理一个异常——让可怜的家伙在F5上调试你的代码。我想这取决于场景,但还有其他答案没有这些问题。比较实际上失败了。您需要调用
ImageFormat.Equals
,而不是使用
=
运算符+1,以便更加勤奋。两个想法:我将重命名为HasJpegExtension和ContainesJPEGHeader。另外,如果文件在检查ext/header和尝试加载之间被删除/移动/etc,您不希望捕获其他异常吗?或者干脆把它们都泡起来会更好吗?当然命名可以改进,并且应该根据您的实际用例进行调整。在这个简单的示例中,我只是选择添加用作后缀的特定方式。最后,我可能会使用
IsJpeg
或您的一些建议。因为这是一个简单的例子,我不想用异常处理来重载它,但通常我会处理与文件io和堆栈中更高的访问权限相关的异常。在上面的函数HasJpegHeader中,我同意FF D8,但它并不总是FF E0。有时它是一个很好的例子。因此,上面的函数导致正确的JPG文件为FALSE。我最初使用的是HasJpegHeader方法。然而,在下面的@OrwellPhille答案中可以找到一个更健壮的变体检查(EXIF文件有不同的标记)。这当然不是一个可靠的检查,因为创建一个满足这些条件的非jpeg文件是微不足道的。我认为它与大量用例成比例。当然,接受非JPEG会有潜在的安全/DoS问题,但我认为这是另一个问题;-)你的答案是一个经典的例子,说明了为什么不应该只给出链接作为答案。这一页现在不见了,答案也没用了。如果你能即兴给出答案,那就太好了,否则应该删除或标记为删除。这是在获取他人内容和允许足够的信用/访问原始材料之间的一条细微的界限。我选择相信消息来源。这里的问题是被引用的用户没有提供到新位置的重定向,甚至没有提供“离开”的重定向。是的,部分同意你的观点。
    public static bool HasJpegHeader(string filename)
    {
        try
        {
            // 0000000: ffd8 ffe0 0010 4a46 4946 0001 0101 0048  ......JFIF.....H
            // 0000000: ffd8 ffe1 14f8 4578 6966 0000 4d4d 002a  ......Exif..MM.*    
            using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.ReadWrite)))
            {
                UInt16 soi = br.ReadUInt16();  // Start of Image (SOI) marker (FFD8)
                UInt16 marker = br.ReadUInt16(); // JFIF marker (FFE0) EXIF marker (FFE1)
                UInt16 markerSize = br.ReadUInt16(); // size of marker data (incl. marker)
                UInt32 four = br.ReadUInt32(); // JFIF 0x4649464a or Exif  0x66697845

                Boolean isJpeg = soi == 0xd8ff && (marker & 0xe0ff) == 0xe0ff;
                Boolean isExif = isJpeg && four == 0x66697845;
                Boolean isJfif = isJpeg && four == 0x4649464a;

                if (isJpeg) 
                {
                    if (isExif)
                        Console.WriteLine("EXIF: {0}", filename);
                    else if (isJfif)
                        Console.WriteLine("JFIF: {0}", filename);
                    else
                        Console.WriteLine("JPEG: {0}", filename);
                }

                return isJpeg;
                return isJfif;
                return isExif;
            }
        }
        catch
        {
            return false;
        }
    }
private bool isJpeg()
        {
string p = currFile.Headers.ContentType.MediaType;
            return p.ToLower().Equals("image/jpeg") || p.ToLower().Equals("image/pjpeg") || p.ToLower().Equals("image/png");
        }
// after check extention of file
byte[] ValidFileSignture = new byte[] { 255, 216, 255, 224 };
byte[] bufferforCheck = new byte[ValidFileSignture.Length];
Stream _inputStream = file.InputStream;
byte[] bufferforCheck1 = new byte[] { 255, 216, 255, 224 };
_inputStream.Read(bufferforCheck, 0, ValidFileSignture.Length);
if (!Enumerable.SequenceEqual(bufferforCheck, ValidFileSignture))
{
    //file OK
}
System.Web.MimeMapping.GetMimeMapping(filename).StartsWith("image/");
MimeMapping.GetMimeMapping produces these results:

file.jpg: image/jpeg
file.gif: image/gif
file.jpeg: image/jpeg
file.png: image/png
file.bmp: image/bmp
file.tiff: image/tiff
file.svg: application/octet-stream