-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathorientation.py
55 lines (50 loc) · 1.96 KB
/
orientation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# Thanks @kylefox
# https://github.com/kylefox/python-image-orientation-patch
from PIL import Image, ImageFile
# PIL's Error "Suspension not allowed here" work around:
# s. http://mail.python.org/pipermail/image-sig/1999-August/000816.html
ImageFile.MAXBLOCK = 1024 * 1024
# The EXIF tag that holds orientation data.
EXIF_ORIENTATION_TAG = 274
# Obviously the only ones to process are 3, 6 and 8.
# All are documented here for thoroughness.
ORIENTATIONS = {
1: ("Normal", 0),
2: ("Mirrored left-to-right", 0),
3: ("Rotated 180 degrees", 180),
4: ("Mirrored top-to-bottom", 0),
5: ("Mirrored along top-left diagonal", 0),
6: ("Rotated 90 degrees", -90),
7: ("Mirrored along top-right diagonal", 0),
8: ("Rotated 270 degrees", -270)
}
def fix_orientation(img, save_over=False):
"""
`img` can be an Image instance or a path to an image file.
`save_over` indicates if the original image file should be replaced by the new image.
* Note: `save_over` is only valid if `img` is a file path.
"""
path = None
if not isinstance(img, Image.Image):
path = img
img = Image.open(path)
elif save_over:
raise ValueError("You can't use `save_over` when passing an Image instance. Use a file path instead.")
try:
orientation = img._getexif()[EXIF_ORIENTATION_TAG]
except (TypeError, KeyError):
return img, 0
if orientation in [3, 6, 8]:
degrees = ORIENTATIONS[orientation][1]
img = img.rotate(degrees)
if save_over and path is not None:
try:
img.save(path, quality=95, optimize=1)
except IOError:
# Try again, without optimization (PIL can't optimize an image
# larger than ImageFile.MAXBLOCK, which is 64k by default).
# Setting ImageFile.MAXBLOCK should fix this....but who knows.
img.save(path, quality=95)
return img, degrees
else:
return img, 0