在没有包含缩略图的PIL的情况下,使用Python在EXIF中指定的方向旋转图像

我有以下情况:

  • 我从iPhone发送一个图像和EXIF信息到我的Pyhon套接字服务器。
  • 我需要根据拍摄图像时的实际方向来正确定位图像。 我知道IOS始终将图像保存为“左侧横向”,并将实际方向添加为EXIF字段(EXIF.Image.Orientation)。
  • 我正在阅读EXIF字段以查看实际的方向。 然后我使用wxpython将图像旋转到正确的方向。

我正在使用pyexiv2进行EXIF操作。

问题:使用wxpython旋转图像时,包含缩略图的EXIF信息丢失。

我做了什么:在旋转图像之前,我正在读取EXIF。 我重置EXIF中的方向字段。 然后我在轮换之后把它放回去。

问题:

EXIF内的缩略图不会旋转。 所以,图像和缩略图有不同的方向。

有问题吗?

有没有其他模块比PIL旋转图像保持其EXIF信息?

有一个单独的EXIF字段的缩略图方向?

有没有一种方法可以单独旋转缩略图?

谢谢你的帮助…

这个解决scheme适用于我: PIL缩略图旋转我的形象?

不需要检查是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 

之前:

之前

后: 后

我find了一个解决scheme…检查出来… 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's 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)