auto-image-orientation-rotator/ApplyImageOrientation.py

111 lines
2.7 KiB
Python
Raw Normal View History

2021-01-04 12:00:05 -08:00
import exif
from exif import Image as ExifImage
from PIL import Image as PilImage
import os
class ApplyImageOrientation:
def __init__(self, input_folder, output_folder):
self.ensure_folder(output_folder)
assert os.path.isdir(input_folder), "Invalid input folder: %s" % input_folder
assert os.path.isdir(output_folder), "Invalid output folder: %s" % output_folder
self.__input_folder = os.path.abspath(input_folder)
self.__output_folder = os.path.abspath(output_folder)
self.__valid_image_extensions = [
"jpeg", "jpg",
"png",
"tiff"
]
def run(self, jpeg=False):
images_paths = self.get_input_images()
for image_path in images_paths:
self.apply_orientation(
image_path=image_path,
jpeg=jpeg
)
@staticmethod
def ensure_folder(folder_path):
os.makedirs(folder_path, exist_ok=True)
def get_input_images(self):
return self.get_directory_images(self.__input_folder)
def get_directory_images(self, path):
images_files_paths = []
for current_dir, subdirs, files in os.walk(path):
for file_name in files:
file_path = os.path.join(current_dir, file_name)
file_basename, file_extension = os.path.splitext(file_path)
if file_extension:
file_extension = file_extension[1:]
file_extension = file_extension.lower()
if file_extension in self.__valid_image_extensions:
images_files_paths.append(file_path)
return images_files_paths
def apply_orientation(self, image_path, jpeg=False):
image_basename = os.path.basename(image_path)
with open(image_path, "rb") as f:
exif_image = ExifImage(f)
orientation = exif_image.orientation
pil_image = PilImage.open(image_path)
rotation_degrees = 0
if orientation == exif.Orientation.LEFT_BOTTOM:
rotation_degrees = 90
if rotation_degrees != 0:
pil_image_rotated = pil_image.rotate(rotation_degrees, expand=True)
else:
pil_image_rotated = pil_image
print(image_basename, pil_image.size, "==>", orientation, "==>", rotation_degrees)
image_rotated_file_path = self.make_image_output_path(image_path=image_path, jpeg=jpeg)
self.ensure_folder(os.path.dirname(image_rotated_file_path))
pil_image_rotated.save(image_rotated_file_path, None if jpeg else "png")
def get_image_relative_path(self, image_path):
image_path_relative = image_path[len(self.__input_folder):]
return image_path_relative
def make_image_output_path(self, image_path, jpeg=False):
image_path_relative = self.get_image_relative_path(image_path=image_path)
image_output_path = self.__output_folder + image_path_relative
if not jpeg:
path_name, extension = os.path.splitext(image_output_path)
image_output_path = path_name + ".png"
return image_output_path