C#如何测试文件是jpeg?

31 c# jpeg

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

谢谢

Dir*_*mar 102

几个选项:

您可以检查文件扩展名:

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);
}
Run Code Online (Sandbox Code Playgroud)

或检查文件标题中的正确幻数:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是加载图像并检查正确的类型.但是,效率较低(除非您打算加载图像),但可能会给您最可靠的结果(请注意加载和解压缩的额外成本以及可能的异常处理):

static bool IsJpegImage(string filename)
{
    try
    {
        using (System.Drawing.Image img = System.Drawing.Image.FromFile(filename)) 
        {           
            // Two image formats can be compared using the Equals method
            // See http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat.aspx
            //
            return img.RawFormat.Equals(System.Drawing.Imaging.ImageFormat.Jpeg);
        }
    }
    catch (OutOfMemoryException)
    {
        // Image.FromFile throws an OutOfMemoryException 
        // if the file does not have a valid image format or
        // GDI+ does not support the pixel format of the file.
        //
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在上面的函数HasJpegHeader中,我同意FF D8,但它并不总是FF E0.有时它是FF E1.因此,上面的函数导致正确的JPG文件为FALSE. (2认同)

Sim*_*bbs 28

以流形式打开文件并查找JPEG 的幻数.

JPEG图像文件以FF D8开头,以FF D9结束.JPEG/JFIF文件包含"JFIF"(4A 46 49 46)的ASCII代码,作为空终止字符串.JPEG/Exif文件包含'Exif'(45 78 69 66)的ASCII代码,也作为空终止字符串


Orw*_*ile 27

OMG,这些代码示例中有很多是错误的,错误的错误.

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

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

    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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • @vaindil我完全是想要哄你,但后来我意识到你实际上已经去维基百科做了自己的研究,不仅注意到数字不同,而且他们实际上是倒退了.所以我会回答你的问题.答案是[Endianness](https://en.wikipedia.org/wiki/Endianness).如果您不想阅读其他维基百科文章,则TL; DR版本为:**英特尔机器将值存储在内存中 - 向后**. (3认同)

Lee*_*Lee 13

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

Image img = Image.FromFile(filePath);
bool isBitmap = img.RawFormat.Equals(ImageFormat.Jpeg);
Run Code Online (Sandbox Code Playgroud)

或者,您可以打开文件并检查标题以获取类型