Изображение повернуто, а миниатюра нет

Я пытаюсь повернуть изображение на основе тега EXIF. Я могу успешно обрабатывать поворот изображения, но миниатюра в проводнике Windows все еще перевернута. Изображение при открытии абсолютно нормальное. Проверена исправленная ориентация здесь. Проблема со следующим кодом заключается в том, что данные EXIF ​​не имеют информация об ориентации миниатюр. Я хочу:

  1. Если доступна ориентация миниатюры, поверните миниатюру и обновите метаданные изображения для ориентации миниатюры.

  2. Если нет доступной информации об ориентации миниатюры, поверните миниатюру и добавьте метаданные изображения для ориентации миниатюры.

Код, который я использую:

public static RotateFlipType RotateImageByExifOrientationData(Image img, string oldFileName, string sourceFilePath, out string newFileName)
{    
    int orientationId = 0x0112;//Image orientation
    int thumbnailOrientationId = 0x5029;//Thumbnail orientation
    var fType = RotateFlipType.RotateNoneFlipNone;

    if (img.PropertyIdList.Contains(orientationId))
    {
        var pItem = img.GetPropertyItem(orientationId);
        //Get the orientation
        fType = GetRotateFlipTypeByExifOrientationData(pItem.Value[0]);
        if (fType != RotateFlipType.RotateNoneFlipNone)
        {
            img.RotateFlip(fType);

            // Read orientation tag. Update to normal so that the other clients(image viewer or browser) will not rotate the rotated image.                                      
            // Force value to 1
            pItem.Value = BitConverter.GetBytes((short)1);
            img.SetPropertyItem(pItem);
            PropertyItem thumbnailItem;
            if (img.PropertyIdList.Contains(thumbnailOrientationId))
            {
                //If thumbnail metadata is available, update it.
                thumbnailItem = img.GetPropertyItem(thumbnailOrientationId);
                thumbnailItem.Value = BitConverter.GetBytes((short)1);
                img.SetPropertyItem(thumbnailItem);
            }
            else
            {
                //If thumbnail metadata is not available, add appropriate metadata.
                thumbnailItem = img.PropertyItems[0];
                thumbnailItem.Id = thumbnailOrientationId;
                thumbnailItem.Type = 2;
                thumbnailItem.Value = BitConverter.GetBytes((short)1);
                thumbnailItem.Len = thumbnailItem.Value.Length;
                img.SetPropertyItem(thumbnailItem);
            }
            newFileName = "Rotated_" + oldFileName;
            string targetFilePath = sourceFilePath + newFileName ;
            ImageFormat targetFormat = ImageFormat.Jpeg;
            img.Save(targetFilePath, targetFormat);
            File.Delete(sourceFilePath + oldFileName);//Delete old file.
        }
    }
    return fType;
}

person User2682    schedule 17.08.2016    source источник
comment
Мое глубокое подозрение заключается в том, что миниатюра просто не соответствует тегам EXIF, поэтому после изменения метаданных EXIF ​​вам нужно заново создать миниатюру.   -  person mcepl    schedule 21.08.2016


Ответы (1)


это старый вопрос, но после некоторых исследований я заметил, что даже после удаления ориентации изображения (0x0112) и ориентации миниатюры (0x5029) при попытке снова создать миниатюру та же ориентация осталась. Поэтому я проверил, что в некоторых JPG миниатюра «встроена» в байты. поэтому после удаления байтов (0x501B) я смог правильно сгенерировать миниатюру.

Простой код показывает:

    var rotateImage = Image.FromStream(fileStream);
    switch (degree)
    {
        case eRotateImagem.Degree_90:
            rotateImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
            break;
        case eRotateImagem.Degree_180:
            rotateImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
            break;
        case eRotateImagem.Degree_270:
            rotateImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
            break;
    }

    int orientationId = 0x0112; //Image orientation
    int thumbnailOrientationId = 0x5029; //Thumbnail orientation
    int thumbnailBytes = 0x501B; //Thumbnail bytes

    if (rotateImage.PropertyIdList.Contains(orientationId))
    {
        rotateImage.RemovePropertyItem(orientationId);
    }
    if (rotateImage.PropertyIdList.Contains(thumbnailOrientationId))
    {
        rotateImage.RemovePropertyItem(thumbnailOrientationId);
    }
    if (rotateImage.PropertyIdList.Contains(thumbnailBytes))
    {
        rotateImage.RemovePropertyItem(thumbnailBytes);
    }
person Alan Llantada    schedule 11.10.2017