Проблемы с чтением метаданных JPEG (ориентация)

У меня есть изображение в формате 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.
   }
}

Любые идеи?


person RPM1984    schedule 03.06.2011    source источник


Ответы (5)


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

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

person spender    schedule 03.06.2011
comment
Iphone5S не работает, фото снято без данных EXIF, есть решение? - person user192344; 20.11.2014
comment
@user192344 user192344, если вы сохраните его как png, он не сохранит EXIF, сохраните его как jpg - person fligant; 05.12.2016

Вот фрагмент, посвященный 8 значениям ориентации.

Сначала несколько заметок:

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

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

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

Ориентир изображения:

Примечание. 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);
}
person ReenignE    schedule 01.05.2014
comment
Гораздо более полный ответ: полное описание случаев ориентации, а также примечание об удалении данных EXIF ​​(на случай, если они будут обработаны позже) - person thomasb; 22.07.2014
comment
очень полезно. это должен быть принятый ответ ИМХО. - person Jeff Doolittle; 24.04.2015
comment
Отличное решение - спасение жизни! - person Ripside; 12.12.2015
comment
Здесь можно найти несколько примеров ориентированных изображений для тестирования: github.com/recurser/exif-orientation-examples - person Krisztián Balla; 28.04.2016

Из этого сообщения похоже, вам нужно проверить 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;
      }
}
person Bala R    schedule 03.06.2011
comment
Хм, тоже пробовал. Было найдено свойство с идентификатором 274, но значением ориентации является 1. Поэтому он не делает флип. - person RPM1984; 03.06.2011
comment
+1 - хотя это неправильный ответ, мои повороты были неправильными - а ваши правильные. - person RPM1984; 03.06.2011
comment
Кроме того, число 3 перевернуто, согласно sylvana.net/jpegcrop/exif_orientation.html. тестирование соглашается. - person DenNukem; 12.01.2013
comment
Это мне очень помогло. Вы можете использовать этот код вместе с случаем для всех ориентаций, чтобы правильно сориентировать любое изображение. - person David C; 05.12.2013

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

    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;
            } 
        }
    }
person Ron Burgundy    schedule 27.01.2014
comment
0x112 = 274, они равны, поэтому вы можете исключить одно из двух из своего оператора if. - person Louis Somers; 03.07.2014
comment
Я пробовал это, но все еще сталкиваюсь с проблемой в мобильном браузере. В веб-браузере работает нормально. Но в Мобиле изображение поворачивается на 90 градусов вправо. помощь? - person Shalin Jirawla; 15.06.2016
comment
@ShalinJirawla У меня была та же проблема: я просто добавил ответ, который исправил ее для меня. - person Darkseal; 19.07.2016
comment
ответ с большим количеством голосов заключался в том, что мои мобильные изображения иногда переворачивались, когда они не нужны (возможно, случай 2,4,5,7). Это сработало лучше для меня! - person deebs; 10.03.2020

Пишу сюда на случай, если у кого-то возникнет такая же проблема. У меня были проблемы с чтением ориентации при производстве с использованием 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);
person Diego Jancic    schedule 30.11.2018
comment
Мне это не помогает, снимки, сделанные на Android и iOS, по-прежнему отображаются в ландшафтном режиме, хотя оба они были сделаны в портретном режиме. - person Mason; 13.11.2020
comment
Проверьте, как вы загружаете изображения, и убедитесь, что загружается оригинал. Если вы обрабатываете/сжимаете изображение перед загрузкой, возможно, вы удаляете важные метаданные. С тех пор этот код работает для меня. - person Diego Jancic; 13.11.2020