Проблема чтения метаданных JPEG (ориентация) - PullRequest
51 голосов
/ 03 июня 2011

У меня есть изображение JPEG, которое было снято на iphone. На моем настольном компьютере (Windows Photo Viewer, Google Chrome и т. Д.) Ориентация неверна.

Я работаю над веб-приложением ASP.NET MVC 3, где мне нужно загрузить фотографии (в настоящее время используется plupload).

У меня есть некоторый серверный код для обработки изображений, включая чтение данных EXIF.

Я пытался прочитать поле PropertyTagOrientation в метаданных EXIF ​​(используя 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 ]

116 голосов
/ 01 мая 2014

Ниже приведен фрагмент, содержащий 8 значений ориентации.

Первые несколько заметок:

Идентификатор EXIF ​​ 0x0112 предназначен для ориентации. Это полезная ссылка EXIF ​​id http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html

0x0112 - это шестнадцатеричный эквивалент 274 . Тип данных PropertyItem.Id - это int, что означает, что 274 - то, что здесь полезно.

Кроме того, 5029 вероятно должен был быть 0x5029 или 20521 , что соответствует ThumbnailOrientation, хотя, скорее всего, здесь не то, что требуется.

Orient Image:

Примечание: img является System.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);
}
17 голосов
/ 03 июня 2011

Похоже, вы забыли, что значения идентификатора ориентации, которые вы искали, находятся в шестнадцатеричном формате. Там, где вы используете 112, вы должны были использовать 0x112.

В этой статье объясняется, как Windows перенаправляет ориентированную ориентацию, а этот кажется довольно актуальным для того, что вы делаете.

14 голосов
/ 03 июня 2011

С это сообщение похоже, что вам нужно проверить 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;
      }
}
11 голосов
/ 27 января 2014

Я объединил данные ответы и комментарии и придумал это:

    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;
            } 
        }
    }
0 голосов
/ 01 декабря 2018

Размещение здесь на тот случай, если у кого-то возникнет такая же проблема. У меня были проблемы с производством при чтении ориентации с использованием 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);
...