阅读JPEG元数据的问题(方向)

时间:2011-06-03 01:15:57

标签: c# image-processing metadata jpeg gdi

我有一张在iphone上拍摄的JPEG图像。在我的台式PC(Windows照片查看器,谷歌浏览器等)上,方向不正确。

我正在开发一个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.
   }
}

有什么想法吗?

5 个答案:

答案 0 :(得分:116)

这是一个解决8个方向值的片段。

首先注意几点:

EXIF ID 0x0112 适用于Orientation。这是一个有用的EXIF ID引用http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html

0x0112 274 的十六进制等效值。 PropertyItem.Id的数据类型为int,这意味着 274 非常有用。

此外, 5029 可能应该是 0x5029 20521 ,这与ThumbnailOrientation相关,但可能不是这里所需要的。< / p>

Orient Image:

注意: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);
}

答案 1 :(得分:17)

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

This article解释了Windows如何提升定位方式,而this one似乎与您正在做的事情非常相关。

答案 2 :(得分:15)

来自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;
      }
}

答案 3 :(得分:12)

我将给出的答案和评论结合起来,然后提出来:

    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;
            } 
        }
    }

答案 4 :(得分:0)

如果有人遇到相同问题,请在此处发布。我在生产中使用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);