c# - 对标记为 ASCII 的 EXIF 属性使用 UTF8 解码是否安全?

标签 c# .net gdi+ exif

我收到了一个图像文件,其 EXIF ImageDescription 元数据的值为“Test accents: éâäàè”。当使用 .NET GDI+ 类提取此数据时,它报告说它存储为 ASCII,但我在使用 ASCII 解码器时得到垃圾数据。通过反复试验,我发现我可以使用 UTF8 解码器正确提取它。

示例代码如下:

public string GetDescription()
{
  const string filePath = @"C:\test_image.jpg";

  using (var bmp = new System.Drawing.Bitmap(filePath))
  {
    var propItem = bmp.PropertyItems.FirstOrDefault(p => p.Id == 270); // EXIF ImageDescription

    if (propItem == null)
      return null;

    string value = null;

    if (propItem.Type == 2) // ASCII
    {
      // Does not work: Returns "Test accents: ??????????"
      var asciiEnc = new System.Text.ASCIIEncoding();
      value = asciiEnc.GetString(propItem.Value, 0, propItem.Value.Length - 1);

      // CORRECT: Returns "Test accents: éâäàè"
      var utf8Enc = new System.Text.UTF8Encoding();
      value = utf8Enc.GetString(propItem.Value, 0, propItem.Value.Length - 1);
    }

    return value;
  }
}

我正在考虑更改生产代码,以便在提取元属性时始终使用 UTF8 解码器,即使 PropertyItem.Type 指示它是 ASCII。它在这种情况下当然有效,但我把它扔给你们,以防万一我遗漏了无法预料的后果。

那么 - 在提取 ASCII 元数据时使用 UTF8 解码器是不是一个坏主意?

PS:我还尝试使用以下代码通过 BitmapMetadata 类提取数据,但得到的结果不正确。如果有一种可靠的方法来使用这种技术,我愿意接受。

// Returns incorrect string: "Test accents: éâäà è"
var value = bitmapMetadata.GetQuery("/app1/ifd/{ushort=270}") as string;

最佳答案

你不能让它可靠。 Exif 遭受了常见的编码问题,Exif 标准规定只能使用 7 位 ASCII 代码,但每个人都忽略了它。他们必须这样做,ASCII 无法正确编码多种语言的文本。顺便说一句,Exif 来自日本,这个国家的语言很少使用 ASCII 和 rich history。编码问题。所以每个人都可以选择适合他们的任何编码,可以是 UTF8 也可以是 ANSI,无论创建图像时常用的代码页是什么。

进退两难,使用UTF8Encoding是最好的选择。它不能很好地处理在 ANSI 代码页中编码的文本,您对此无能为力。 Encoding.Default 是一个糟糕的第二选择。图片中的文本实际上是 utf-8 编码的。

但是,是的,如果文本实际上是纯 ASCII,那么 UTF8Encoding 就可以正常工作。 Utf-8 以相同的方式对 ASCII 码进行编码。

关于c# - 对标记为 ASCII 的 EXIF 属性使用 UTF8 解码是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19284205/

相关文章:

c# - 多线程系统.Windows.图形

C# 手机游戏开发

c# - 如何处理 NLog 的所有事件属性布局渲染器生成的空值?

c# - 如何小写 Visual Studio Code Snippet 变量?

c# - 实体类型的 EF 映射属性到具有 TPH 继承的多个表

mysql - 使用.NET执行MySQL的SQL文件

.net - 分层企业应用程序中的 WPF MVVM 架构

c# - Pen.Dispose 是否处理底层画笔?

c# - 从格式 dd.MM.yyyy hh :mm:ss 将字符串解析为 .net 核心中的日期时间

c# - 用C#/NewtonSoft反序列化JSON时,能不能把一些结果展平?