【问题标题】:Problem reading JPEG Metadata (Orientation)读取 JPEG 元数据(方向)时出现问题
【发布时间】:2011-09-07 12:01:18
【问题描述】:

我有一张在 iPhone 上拍摄的 JPEG 图像。在我的台式电脑(Windows 照片查看器、Google Chrome 等)上,方向不正确。

我正在开发一个 ASP.NET MVC 3 Web 应用程序,我需要在其中上传照片(目前使用 plupload)。

我有一些服务器端代码来处理图像,包括读取 EXIF 数据。

我已尝试读取 EXIF 元数据中的 PropertyTagOrientation 字段(使用 GDI - Image.PropertyItems),但该字段不存在。

所以它要么是一些特定的 iphone 元数据,要么是一些其他的元数据。

我使用了另一个工具,例如 Aurigma Photo Uploader,它可以正确读取元数据并旋转图像。它是如何做到的?

有谁知道其他哪些 JPEG 元数据可能包含所需的信息,以便知道它需要被 Aurigma 使用旋转?

这是我用来读取 EXIF 数据的代码:

var image = Image.FromStream(fileStream);

foreach (var prop in image.PropertyItems)
{
   if (prop.Id == 112 || prop.Id == 5029)
   {
      // do my rotate code - e.g "RotateFlip"
      // Never get's in here - can't find these properties.
   }
}

有什么想法吗?

【问题讨论】:

    标签: c# image-processing metadata jpeg gdi


    【解决方案1】:

    这是一个处理 8 个方向值的 sn-p。

    首先要注意几点:

    EXIF id 0x0112 用于方向。这是一个有用的 EXIF id 参考 http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html

    0x0112274 的十六进制等效值。 PropertyItem.Id 的数据类型是 int,这意味着 274 在这里有用。

    此外,5029 可能应该是与 ThumbnailOrientation 相关的 0x502920521,但这可能不是这里想要的。

    东方图像:

    注意:imgSystem.Drawing.Image 或继承自它,例如 System.Drawing.Bitmap

    if (Array.IndexOf(img.PropertyIdList, 274) > -1)
    {
        var orientation = (int)img.GetPropertyItem(274).Value[0];
        switch (orientation)
        {
            case 1:
                // No rotation required.
                break;
            case 2:
                img.RotateFlip(RotateFlipType.RotateNoneFlipX);
                break;
            case 3:
                img.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break;
            case 4:
                img.RotateFlip(RotateFlipType.Rotate180FlipX);
                break;
            case 5:
                img.RotateFlip(RotateFlipType.Rotate90FlipX);
                break;
            case 6:
                img.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break;
            case 7:
                img.RotateFlip(RotateFlipType.Rotate270FlipX);
                break;
            case 8:
                img.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break;
        }
        // This EXIF data is now invalid and should be removed.
        img.RemovePropertyItem(274);
    }
    

    【讨论】:

    • 更完整的答案:方向案例的完整描述,以及删除 EXIF 数据的注释(以防稍后处理)
    • 非常有帮助。恕我直言,这应该是公认的答案。
    • 伟大的解决方案 - 一个救生员!
    • 这里可以找到一些用于测试的定向图像示例:github.com/recurser/exif-orientation-examples
    【解决方案2】:

    您似乎忘记了您查找的方向 ID 值是十六进制的。在你使用 112 的地方,你应该使用 0x112。

    This article 解释了 Windows 如何实现定向处理,this one 似乎与您正在做的事情非常相关。

    【讨论】:

    • Iphone5S 不工作,拍照时没有 EXIF 数据,有什么解决办法吗?
    • @user192344 如果你将它保存为 png 它不会保存 EXIF 将它保存为 jpg
    【解决方案3】:

    来自this post 看来您需要检查 ID 274

    foreach (PropertyItem p in properties) {
          if (p.Id == 274) {
                Orientation = (int)p.Value[0];
             if (Orientation == 6)
                oldImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
             if (Orientation == 8)
                oldImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
          break;
          }
    }
    

    【讨论】:

    • 嗯,也试过了。它找到了一个 id 为274 的属性,但方向值为1。所以它不会翻转。
    • +1 - 虽然这不是正确的答案,但我的轮换是错误的 - 而你的轮换是对的。
    • 另外,“3”是颠倒的,根据sylvana.net/jpegcrop/exif_orientation.html我的测试同意。
    • 这对我帮助很大。您可以将此代码与所有方向的案例一起使用,以正确定位任何图像。
    【解决方案4】:

    我结合了给定的答案和 cmets 并得出了这个:

        MemoryStream stream = new MemoryStream(data);
        Image image = Image.FromStream(stream);
    
        foreach (var prop in image.PropertyItems) {
            if ((prop.Id == 0x0112 || prop.Id == 5029 || prop.Id == 274)) {
                var value = (int)prop.Value[0];
                if (value == 6) {
                    image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    break;
                } else if (value == 8) {
                    image.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    break;
                } else if (value == 3) {
                    image.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    break;
                } 
            }
        }
    

    【讨论】:

    • 0x112 = 274,它们是相等的,因此您可以在 if 语句中留下两者之一。
    • 我试过了,但在移动浏览器中仍然遇到问题。在 Web 浏览器中它工作正常。但在 Mobile 中,图像向右旋转 90 度。帮忙?
    • @ShalinJirawla 我遇到了同样的问题:刚刚添加了一个为我修复的答案。
    • 获得更多支持的答案是有时在不需要时翻转我的移动图像(可能是案例 2、4、5、7)。这对我来说效果更好!
    【解决方案5】:

    在这里发帖以防万一有人遇到同样的问题。我在使用 WFP 和 GDI 读取方向时遇到问题。唯一有效的是使用:https://github.com/dlemstra/Magick.NET

    代码相当简单:

    var img = new MagickImage(inputStream);
    img.AutoOrient();   // Fix orientation
    img.Strip();        // remove all EXIF information
    img.Write(outputPath);
    

    【讨论】:

    • 这并不能解决我的问题,在 Android 和 iOS 上拍摄的照片仍然以横向显示,而它们都是以纵向模式拍摄的。
    • 检查您上传图片的方式并确保上传的是原件。如果您在上传之前正在处理/压缩图像,那么您可能正在删除重要的元数据。从那以后,该代码一直对我有用。
    猜你喜欢
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多