-
-
Save BuhtigithuB/ae9d2abd790a6659ed1a37d4b9aaf7cb to your computer and use it in GitHub Desktop.
Autorotate and autoresize images in mass with Python and PIL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
File: autorotate.py | |
Origial Author: Damien Riquet <d.riquet@gmail.com> | |
Current Maintainer: Trinh Nguyen <dangtrinhnt[at]gmail[dot]com> | |
Description: This script provides an auto-rotate feature of pictures | |
USAGE: autorotate.py [-h] [--recursive] directory [directory ...] | |
positional arguments: | |
directory | |
optional arguments: | |
-h, --help show this help message and exit | |
--recursive, -r | |
""" | |
import os, re, argparse | |
from PIL import Image | |
# this will help you bypass the truncated images | |
# the truncated images will be completed to full size with gray color. | |
from PIL import ImageFile | |
ImageFile.LOAD_TRUNCATED_IMAGES = True | |
picture_re = re.compile(r'.*\.jpg$', re.IGNORECASE) | |
def autorotate(path): | |
""" This function autorotates a picture """ | |
ret = False | |
image = Image.open(path) | |
try: | |
exif = image._getexif() | |
except AttributeError as e: | |
print "Could not get exif - Bad image!" | |
ret = False | |
(width, height) = image.size | |
# print "\n===Width x Heigh: %s x %s" % (width, height) | |
if exif: | |
orientation_key = 274 # cf ExifTags | |
if orientation_key in exif: | |
orientation = exif[orientation_key] | |
rotate_values = {3: 180, | |
6: 270, | |
8: 90} | |
if orientation in rotate_values: | |
# Rotate and save the picture | |
image = image.rotate(rotate_values[orientation], expand=True) | |
exif[274] = 1 | |
image.save(path, quality=100, exif=str(exif)) | |
ret = True | |
else: | |
if width > height: | |
# We guess the rotation to apply here | |
image = image.rotate(90, expand=True) | |
image.save(path, quality=100) | |
ret= True | |
return ret | |
# new_width = 200 | |
# new_height = 300 | |
def autoresize(path, new_width, new_height): | |
ret = False | |
image = Image.open(path) | |
(width, height) = image.size | |
if width < height: | |
if width != new_width and height != new_height: | |
image = image.resize((new_width, new_height), Image.ANTIALIAS) | |
image.save(path, quality=100) | |
ret = True | |
return ret | |
def process_directory(path, recursive=False, new_width=None, new_height=None): | |
""" This function processes all elements from a directory """ | |
print "\n==new_width: %s\n" % new_width | |
print "\n==new_height: %s\n" % new_height | |
if not os.path.isdir(path): | |
print path, 'is not a directory' | |
else: | |
for elt in os.listdir(path): | |
elt_path = os.path.join(path, elt) | |
if os.path.isdir(elt_path) and recursive: | |
process_directory(elt_path, recursive) | |
elif os.path.isfile(elt_path): | |
if re.match(picture_re, elt_path): | |
print "=== Processing %s ===" % (elt) | |
for i in range(2): # for some reason, I have to do it twice | |
if autorotate(elt_path): | |
print 'autorotate: %s/%s' % (path, elt) | |
if new_width and new_height: | |
if autoresize(elt_path, new_width, new_height): | |
print 'autoresize: %s/%s' % (path, elt) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser() | |
parser.add_argument('--dir', '-d', nargs='+') | |
parser.add_argument('--recursive', '-r', action='store_true') | |
parser.add_argument('--resize', nargs='+') | |
args = parser.parse_args() | |
width = None | |
height = None | |
if args.resize: | |
if len(args.resize) == 2: | |
width = int(args.resize[0]) | |
height = int(args.resize[1]) | |
for d in args.dir: | |
process_directory(d, args.recursive, width, height) |
Exif get rewrite without being updated following the retoation... So when run multiple time it keeps wrongly rotating the file... Also I forgot to update image.rotatet() with expand=True in a couple of statment...
Rotate occurs more than once the logic in autorotate is convulated... There is also many exit point to the rotate function which is not a good practices...
Here the less convulated code and single exist point, expand=True everywhere...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works better with expand=True