如何使用标头字节确定图像的编码

问题描述 投票:0回答:3

所以我使用c#,我需要确定图像文件的实际编码。大多数图像可以采用一种格式,同时具有不同的扩展名,并且通常仍然可以工作。

我的需求是需要对图像格式有精确的了解。

还有另外一个线程处理此问题:确定图像文件的图像编码

本节展示了如何在获得图像的标头信息后找到实际的编码。 我需要打开图像并提取此标题信息。

FileStream imageFile = new FileStream("myImage.gif", FileMode.Open);

在这之后,我如何仅打开包含标头的字节?

谢谢你。

c# image encoding gdi
3个回答
2
投票

好吧,我最后想通了。所以我要更新线程并关闭它。我的解决方案的唯一问题是它需要打开整个图像文件,而不仅仅是所需的字节。 这会使用更多内存,并且需要更长的时间。因此,当考虑速度时,这不是最佳解决方案。

只是为了给予应得的信任,此代码是从 stack-overflow 上有几个来源,您可以在以下位置找到链接 OP和之前的评论。其余的代码是我写的。

如果有人想修改代码以仅打开正确数量的字节,请随意。

TextWriterTraceListener writer = new TextWriterTraceListener(System.Console.Out);
Debug.Listeners.Add(writer);

// PNG file contains 8 - bytes header.

// JPEG file contains 2 - bytes header(SOI) followed by series of markers,
// some markers can be followed by data array. Each type of marker has different header format.
// The bytes where the image is stored follows SOF0 marker(10 - bytes length).
// However, between JPEG header and SOF0 marker there can be other segments.

// BMP file contains 14 - bytes header.

// GIF file contains at least 14 bytes in its header.

FileStream memStream = new FileStream(@"C:\\a.png", FileMode.Open);

Image fileImage = Image.FromStream(memStream);
    
//get image format
var fileImageFormat = typeof(System.Drawing.Imaging.ImageFormat).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).ToList().ConvertAll(property => property.GetValue(null, null)).Single(image_format => image_format.Equals(fileImage.RawFormat));

MessageBox.Show("File Format: " + fileImageFormat);


//get image codec
var fileImageFormatCodec = System.Drawing.Imaging.ImageCodecInfo.GetImageDecoders().ToList().Single(image_codec => image_codec.FormatID == fileImage.RawFormat.Guid);

MessageBox.Show("MimeType: " + fileImageFormatCodec.MimeType + " \n" + "Extension: " + fileImageFormatCodec.FilenameExtension + "\n" + "Actual Codec: " + fileImageFormatCodec.CodecName);

输出符合预期:

文件图像格式:Png

内置 PNG 编解码器,mime:image/png,扩展名:*.PNG


2
投票

除非您知道标题的大小,否则您无法真正阅读“仅标题”。

相反,确定您需要能够区分需要支持的格式的最小字节数,并只读取这些字节。您需要的所有格式很可能都有一个唯一的标头。

例如,如果您需要支持 png 和 jpeg,这些格式以:

  PNG: 89 50 4E 47 0D 0A 1A 0A
 JPEG: FF D8 FF E0

因此在这种情况下,您只需读取一个字节即可区分两者。实际上,我会说多使用几个字节,以防万一您遇到其他文件格式。

要从文件开头读取 8 个字节:

using( var sr = new FileStream( "file", FileMode.Open ) )
{
    var data = new byte[8];
    int numRead = sr.Read( data, 0, data.Length );
    // numRead gives you the number of bytes read
}

0
投票

Mime-Detective NuGet 包提供易于使用的 API 来动态检查文件 MIME。这有很多(大约 14k)二进制文件签名,它应该可以防止您遇到压缩类型问题,这可能会影响 SOI。

https://github.com/MediatedCommunications/Mime-Detective

唯一的限制是纯文本文件(因为它们通常没有任何十六进制 SOI 字节)。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.