Fix EXIF orientation in API image loading
This commit is contained in:
parent
c8a5322d1f
commit
67d8dafe44
|
@ -86,6 +86,7 @@ def decode_base64_to_image(encoding):
|
|||
response = requests.get(encoding, timeout=30, headers=headers)
|
||||
try:
|
||||
image = Image.open(BytesIO(response.content))
|
||||
image = images.apply_exif_orientation(image)
|
||||
return image
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail="Invalid image url") from e
|
||||
|
@ -94,6 +95,7 @@ def decode_base64_to_image(encoding):
|
|||
encoding = encoding.split(";")[1].split(",")[1]
|
||||
try:
|
||||
image = Image.open(BytesIO(base64.b64decode(encoding)))
|
||||
image = images.apply_exif_orientation(image)
|
||||
return image
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail="Invalid encoded image") from e
|
||||
|
|
|
@ -797,3 +797,52 @@ def flatten(img, bgcolor):
|
|||
|
||||
return img.convert('RGB')
|
||||
|
||||
|
||||
# https://www.exiv2.org/tags.html
|
||||
_EXIF_ORIENT = 274 # exif 'Orientation' tag
|
||||
|
||||
def apply_exif_orientation(image):
|
||||
"""
|
||||
Applies the exif orientation correctly.
|
||||
|
||||
This code exists per the bug:
|
||||
https://github.com/python-pillow/Pillow/issues/3973
|
||||
with the function `ImageOps.exif_transpose`. The Pillow source raises errors with
|
||||
various methods, especially `tobytes`
|
||||
|
||||
Function based on:
|
||||
https://github.com/wkentaro/labelme/blob/v4.5.4/labelme/utils/image.py#L59
|
||||
https://github.com/python-pillow/Pillow/blob/7.1.2/src/PIL/ImageOps.py#L527
|
||||
|
||||
Args:
|
||||
image (PIL.Image): a PIL image
|
||||
|
||||
Returns:
|
||||
(PIL.Image): the PIL image with exif orientation applied, if applicable
|
||||
"""
|
||||
if not hasattr(image, "getexif"):
|
||||
return image
|
||||
|
||||
try:
|
||||
exif = image.getexif()
|
||||
except Exception: # https://github.com/facebookresearch/detectron2/issues/1885
|
||||
exif = None
|
||||
|
||||
if exif is None:
|
||||
return image
|
||||
|
||||
orientation = exif.get(_EXIF_ORIENT)
|
||||
|
||||
method = {
|
||||
2: Image.FLIP_LEFT_RIGHT,
|
||||
3: Image.ROTATE_180,
|
||||
4: Image.FLIP_TOP_BOTTOM,
|
||||
5: Image.TRANSPOSE,
|
||||
6: Image.ROTATE_270,
|
||||
7: Image.TRANSVERSE,
|
||||
8: Image.ROTATE_90,
|
||||
}.get(orientation)
|
||||
|
||||
if method is not None:
|
||||
return image.transpose(method)
|
||||
return image
|
||||
|
|
Loading…
Reference in New Issue