I need some of my pictures to be displayed with the same orientation whether the software reads the exif data or not. One solution (the only one that could fit actually) would be to rotate the image according to the exif tag if it exists and then delete or modify this tag to '1'.
Example
Let's say an image has the Orientation exif tag set to 3. What I want to do is rotate this image according to this tag and save it this way. So that a software that doesn't interpret exif will still display it in the good orientation. Though if the exif tag Orientation is still set to 3, then a software that interprets Exif will rotate my already-rotated image. So that's why I want to set this tag to 1 (which means : no orientation) or delete it.
My final goal is that the image will always be displayed the same, whichever software I use to open it.
There are a lot of questions about that, Exif and Python, blah blah blah. Here is a list of libs that I heard about :
What are the best practices ? Is there a pure python solution ? (Which I could install with pip and put it in my requirements.txt) Is there some kind of new lib I could use which is specific to Python3 ?
My only problem right now is to modify and write those exif data to the image file. I have no problem to read exif data, and rotate the image according to the orientation tag. Any tips or advice on that ?
This answer works for Python2.7 - you can probably just swap Pillow for PIL in Python3, but I can't speak to that from experience. Note that unlike pyexiv2 and most of the other packages that allow you to modify EXIF metadata, the pexif library is standalone and pure python, so it does not need to bind to any C libraries that may not be present on your machine.
You need to use two separate tools for the two steps:
Four steps:
If the orientation tag isn't found, an AttributeError results, hence the try:
. Also note that pexif needs the orientation tag to be a list (with one element).
import pexif
img = pexif.JpegFile.fromFile(temp_dir + filename)
try:
#Get the orientation if it exists
orientation = img.exif.primary.Orientation[0]
img.exif.primary.Orientation = [1]
img.writeFile(temp_dir + filename)
Now to rotate the image. A source for the meaning of the possible orientations (used to generate the lookup table for rotations) is here.
from PIL import Image
img = Image.open(temp_dir + filename)
if orientation is 6: img = img.rotate(-90)
elif orientation is 8: img = img.rotate(90)
elif orientation is 3: img = img.rotate(180)
elif orientation is 2: img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 5: img = img.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 7: img = img.rotate(90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 4: img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
#save the result
img.save(temp_dir + filename)
if ctype == 'image/jpeg':
from PIL import Image
import pexif
img = pexif.JpegFile.fromFile(temp_dir + filename)
try:
#Get the orientation if it exists
orientation = img.exif.primary.Orientation[0]
img.exif.primary.Orientation = [1]
img.writeFile(temp_dir + filename)
#now rotate the image using the Python Image Library (PIL)
img = Image.open(temp_dir + filename)
if orientation is 6: img = img.rotate(-90)
elif orientation is 8: img = img.rotate(90)
elif orientation is 3: img = img.rotate(180)
elif orientation is 2: img = img.transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 5: img = img.rotate(-90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 7: img = img.rotate(90).transpose(Image.FLIP_LEFT_RIGHT)
elif orientation is 4: img = img.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
#save the result
img.save(temp_dir + filename)
except: pass