Вращение изображения с ориентацией, указанной в EXIF, с использованием Python без PIL, включая миниатюру

У меня есть следующий сценарий:

  • Я отправляю изображение с iPhone вместе с информацией EXIF ​​на мой сервер сокетов Pyhon.
  • Мне нужно, чтобы изображение было правильно ориентировано на основе фактической ориентации при съемке изображения. Я знаю, что IOS всегда сохраняет изображение как Landscape Left и добавляет фактическую ориентацию в поле EXIF ​​(EXIF.Image.Orientation).
  • Я читаю поле EXIF, чтобы увидеть фактическую ориентацию. Затем я поворачиваю изображение, используя wxpython для правильной ориентации.

Я использую pyexiv2 для обработки EXIF.

Проблема: информация EXIF, включающая миниатюры, потерянные при вращении изображения с использованием wxpython.

Что я сделал: я читаю EXIF ​​перед тем, как поворачивать изображение. я reset поле ориентации в EXIF. Затем я возвращаю его после вращения.

Проблема:

Миниатюра внутри EXIF ​​не поворачивается. Таким образом, изображение и миниатюра имеют разные ориентации.

Вопросы?

Есть ли какой-либо модуль, отличный от PIL, для поворота изображения, сохраняющего его информацию EXIF?

Есть ли отдельное поле EXIF ​​для ориентации эскизов?

Есть ли способ, которым я могу просто повернуть миниатюру?

Спасибо за вашу помощь...

Ответ 1

Я нашел решение... проверьте это... http://www.atoztoa.com/2012/12/rotate-images-along-with-thumbnails-in.html

'''
Rotate Image
'''
import pyexiv2
import wx
import cStringIO
import os

def rotateImage(infile, device):
    try:
        # Read Metadata from the image
        metadata = pyexiv2.metadata.ImageMetadata(infile)
        metadata.read();

        # Let get the orientation
        orientation = metadata.__getitem__("Exif.Image.Orientation")
        orientation = int(str(orientation).split("=")[1][1:-1])

        # Extract thumbnail
        thumb = metadata.exif_thumbnail

        angle = 0

        # Check the orientation field in EXIF and rotate image accordingly
        if device == "iPhone" or device == "iPad":
            # Landscape Left : Do nothing
            if orientation == ORIENTATION_NORMAL:
                angle = 0
            # Portrait Normal : Rotate Right
            elif orientation == ORIENTATION_LEFT:
                angle = -90
            # Landscape Right : Rotate Right Twice
            elif orientation == ORIENTATION_DOWN:
                angle = 180
            # Portrait Upside Down : Rotate Left
            elif orientation == ORIENTATION_RIGHT:
                angle = 90

            # Resetting Exif field to normal
            print "Resetting exif..."
            orientation = 1
            metadata.__setitem__("Exif.Image.Orientation", orientation)

        # Rotate
        if angle != 0:
            # Just rotating the image based on the angle
            print "Rotating image..."
            angle = math.radians(angle)
            img = wx.Image(infile, wx.BITMAP_TYPE_ANY)
            img_centre = wx.Point( img.GetWidth()/2, img.GetHeight()/2 )
            img = img.Rotate( angle, img_centre, True )
            img.SaveFile(infile, wx.BITMAP_TYPE_JPEG)

            # Create a stream out of the thumbnail and rotate it using wx
            # Save the rotated image to a temporary file
            print "Rotating thumbnail..."
            t = wx.EmptyImage(100, 100)
            thumbStream = cStringIO.StringIO(thumb.data)
            t.LoadStream(thumbStream, wx.BITMAP_TYPE_ANY)
            t_centre = wx.Point( t.GetWidth()/2, t.GetHeight()/2 )
            t = t.Rotate( angle, t_centre, True )
            t.SaveFile(infile + ".jpg", wx.BITMAP_TYPE_JPEG)
            thumbStream.close()

            # Read the rotated thumbnail and put it back in the rotated image
            thumb.data = open(infile + ".jpg", "rb").read();
            # Remove temporary file
            os.remove(infile + ".jpg")

        # Write back metadata
        metadata.write();

    except Exception, e:
        print "Error rotating image... : " + str(e)

Ответ 2

Это решение работает для меня: PIL thumbnail поворачивает мое изображение?

Не нужно проверять, действительно ли это iPhone или iPad: если фотография имеет указатель ориентации - повернуть его.

from PIL import Image, ExifTags

try:
    image=Image.open(filepath)
    for orientation in ExifTags.TAGS.keys():
        if ExifTags.TAGS[orientation]=='Orientation':
            break
    exif=dict(image._getexif().items())

    if exif[orientation] == 3:
        image=image.rotate(180, expand=True)
    elif exif[orientation] == 6:
        image=image.rotate(270, expand=True)
    elif exif[orientation] == 8:
        image=image.rotate(90, expand=True)
    image.save(filepath)
    image.close()

except (AttributeError, KeyError, IndexError):
    # cases: image don't have getexif
    pass

До:

Before

После того, как: After

Ответ 3

Если вы используете Pillow> = 6.0.0, вы можете использовать встроенную функцию, чтобы правильно повернуть изображение в соответствии с его тегом exif:

from PIL import ImageOps

image = ImageOps.exif_transpose(image)

Ответ 4

https://medium.com/@giovanni_cortes/rotate-image-in-django-when-saved-in-a-model-8fd98aac8f2a

Это сообщение в блоге объясняет это четко. Просто убедитесь, что вы пытаетесь сохранить код @receiver.. в forms.py или models.py, так как я получил ошибки cannot import model/view.

сохраните метод rotate_image в models.py &   @receiver.. также в models.py.

Я также получил такие ошибки, как No такой каталог. Просто убедитесь, что full_path правильно установлен в папку с носителями.

Я использовал эту строку

fullpath = os.path.join(os.path.dirname(BASE_DIR)) + instance.fimage.url