131 lines
5.5 KiB
Python
131 lines
5.5 KiB
Python
import re
|
|
import os
|
|
from datetime import datetime
|
|
from optima35.image_handler import ImageProcessor, ExifHandler
|
|
from optima35 import __version__
|
|
|
|
class OptimaManager:
|
|
def __init__(self):
|
|
self.name = "optima35"
|
|
self.version = __version__
|
|
self.image_processor = ImageProcessor()
|
|
self.exif_handler = ExifHandler()
|
|
|
|
def modify_timestamp_in_exif(self, data_for_exif: dict, filename: str):
|
|
""""Takes a dict formated for exif use by piexif and adjusts the date_time_original, changing the minutes and seconds to fit the number of the filname."""
|
|
last_three = filename[-3:len(filename)]
|
|
total_seconds = int(re.sub(r'\D+', '', last_three))
|
|
minutes = total_seconds // 60
|
|
seconds = total_seconds % 60
|
|
time = datetime.strptime(data_for_exif["date_time_original"], "%Y:%m:%d %H:%M:%S") # change date time string back to an time object for modification
|
|
new_time = time.replace(hour=12, minute=minutes, second=seconds)
|
|
data_for_exif["date_time_original"] = new_time.strftime("%Y:%m:%d %H:%M:%S")
|
|
return data_for_exif
|
|
|
|
def process_image(self, # TODO: split into two classes, one for modification for one saving..
|
|
image_input_file,
|
|
image_output_file,
|
|
file_type = "jpg",
|
|
quality = 90,
|
|
compressing = 6,
|
|
optimize = False,
|
|
resize = None,
|
|
watermark = None,
|
|
font_size = 2,
|
|
grayscale = False,
|
|
brightness = None,
|
|
contrast = None,
|
|
dict_for_exif = None,
|
|
gps = None,
|
|
copy_exif = False,
|
|
save = True):
|
|
# Partly optimized by ChatGPT
|
|
# Open the image file
|
|
with self.image_processor.open_image(image_input_file) as img:
|
|
processed_img = img
|
|
image_name = os.path.basename(image_output_file) # for date adjustment
|
|
# Resize
|
|
if resize is not None:
|
|
processed_img = self.image_processor.resize_image(
|
|
image=processed_img, percent = resize
|
|
)
|
|
|
|
# Watermark
|
|
if watermark is not None:
|
|
processed_img = self.image_processor.add_watermark(
|
|
processed_img, watermark, int(font_size)
|
|
)
|
|
|
|
# Grayscale
|
|
if grayscale:
|
|
processed_img = self.image_processor.grayscale(processed_img)
|
|
|
|
# Brightness
|
|
if brightness is not None:
|
|
processed_img = self.image_processor.change_brightness(
|
|
processed_img, brightness
|
|
)
|
|
|
|
# Contrast
|
|
if contrast is not None:
|
|
processed_img = self.image_processor.change_contrast(
|
|
processed_img, contrast
|
|
)
|
|
|
|
# EXIF data handling
|
|
exif_piexif_format = None
|
|
if dict_for_exif: # todo: maybe move to ui and only accept complete exif dicts..
|
|
selected_exif = dict_for_exif
|
|
if "date_time_original" in dict_for_exif:
|
|
selected_exif = self.modify_timestamp_in_exif(selected_exif, image_name)
|
|
exif_piexif_format = self.exif_handler.build_exif_bytes(
|
|
selected_exif, self.image_processor.get_image_size(processed_img)
|
|
)
|
|
|
|
# GPS data
|
|
if gps is not None:
|
|
latitude = float(gps[0])
|
|
longitude = float(gps[1])
|
|
exif_piexif_format = self.exif_handler.add_geolocation_to_exif(exif_piexif_format, latitude, longitude)
|
|
|
|
# Copy EXIF data if selected, and ensure size is correct in exif data
|
|
elif copy_exif:
|
|
try:
|
|
og_exif = self.exif_handler.get_exif_info(img)
|
|
og_exif["Exif"][40962], og_exif["Exif"][40963] = self.image_processor.get_image_size(processed_img)
|
|
exif_piexif_format = og_exif
|
|
except Exception:
|
|
print("Copying EXIF data selected, but no EXIF data is available in the original image file.")
|
|
|
|
if save:
|
|
# Save the processed image
|
|
self.image_processor.save_image(
|
|
image = processed_img,
|
|
path = image_output_file,
|
|
piexif_exif_data = exif_piexif_format,
|
|
file_type = file_type,
|
|
jpg_quality = quality,
|
|
png_compressing = compressing,
|
|
optimize = optimize
|
|
)
|
|
else:
|
|
return self.image_processor.convert_pil_to_qtimage(processed_img)
|
|
|
|
def insert_dict_to_image(self, exif_dict, image_path, gps = None):
|
|
image_name, ending = os.path.splitext(os.path.basename(image_path))
|
|
img = self.image_processor.open_image(image_path)
|
|
selected_exif = exif_dict
|
|
if "date_time_original" in exif_dict:
|
|
selected_exif = self.modify_timestamp_in_exif(selected_exif, image_name)
|
|
|
|
exif_piexif_format = self.exif_handler.build_exif_bytes(
|
|
selected_exif, self.image_processor.get_image_size(img)
|
|
)
|
|
|
|
# GPS data
|
|
if gps is not None:
|
|
latitude = gps[0]
|
|
longitude = gps[1]
|
|
exif_piexif_format = self.exif_handler.add_geolocation_to_exif(exif_piexif_format, latitude, longitude)
|
|
|
|
self.exif_handler.insert_exif(exif_dict = exif_piexif_format, img_path = image_path)
|