I need to take photos in iPhone and save it in my PC. The images should have the same orientation as when it was taken.
The Details
I have my own iPhone app which will take the image and send it as raw data through TCP sockets to the python server running on my PC. The python server receives the image and saves it as JPG in the proper location.
The First Problem
iOS always saves the image as landscape even if we take the photo in portrait mode. The actual orientation is embedded in the EXIF header of the image. Apple devices properly reads the EXIF information and will always display the images properly. But most of the image viewers in Windows doesn't care about the field. So, all images will be displayed as landscape in the PC.
The Solution
When I receive the image at the python server, I do the following:
- Check the proper orientation by reading the EXIF using pyexvi2.
- Rotate the image to match the actual orientation using wxpython. This will remove the EXIF header.
- Reset the orientation tag in EXIF so that the image will display as-is everywhere.
- Put back the EXIF information into the rotated image.
This actually makes the image display properly. But...
The Second Problem
The thumbnail inside the EXIF is not rotated. As we are doing the EXIF separately, the thumbnail is not processed by anyone.
The Complete Solution
I am taking the thumbnail out of the EXIF, rotating it and putting it back in the EXIF.
Here is the complete code...
'''
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 + ".tmp", wx.BITMAP_TYPE_JPEG)
thumbStream.close()
# Read the rotated thumbnail and put it back in the rotated image
thumb.data = open(infile + ".tmp", "rb").read();
# Remove temporary file
os.remove(infile + ".tmp")
# Write back metadata
metadata.write();
except Exception, e:
print "Error rotating image... : " + str(e)
Bonus material: Here is how to get the GPS coordinates from an image in Python...
1 comments:
500-651 exam dumps - Free Cisco Adv anced Security Architecture for Systems Engineers Exam Questions & Dumps. 100% Free 500-651 ETE Files With Updated
Post a Comment