diff --git a/optima/optima35.py b/optima/optima35.py index 8345e3b..9646b73 100644 --- a/optima/optima35.py +++ b/optima/optima35.py @@ -1,113 +1,108 @@ import re import os from datetime import datetime -# My packages -from utils.image_handler import ImageProcessor, ExifHandler +from optima.image_handler import ImageProcessor, ExifHandler class OPTIMA35: def __init__(self): self.name = "OPTIMA-35" - self.version = "0.4.1" + self.version = "0.5.0" self.image_processor = ImageProcessor() self.exif_handler = ExifHandler() - self.settings = { - "input_folder": None, - "output_folder": None, - "file_format": None, - "resize": False, - "contrast": False, - "brightness": False, - "new_file_names": False, - "invert_image_order": False, - "copy_exif": False, - "own_exif": False, - "watermark": False, - "grayscale": False, - "jpg_quality": None, - "png_compression": None, - "font_size": None, - "optimize": False, - "gps": False - } - self.selected_exif = {} - def modify_timestamp_in_exif(self, exif_data, filename): - """"Takes exif data and adjust time to fit ending of filename.""" - try: - last_tree = filename[-3:len(filename)] - total_seconds = int(re.sub(r'\D+', '', last_tree)) - minutes = total_seconds // 60 - seconds = total_seconds % 60 - time = datetime.strptime(exif_data["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) - exif_data["date_time_original"] = new_time.strftime("%Y:%m:%d %H:%M:%S") - return exif_data + 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_tree = filename[-3:len(filename)] + total_seconds = int(re.sub(r'\D+', '', last_tree)) + 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 - except ValueError: - print("Modifying date went wrong, exiting...") - exit() - - def process(self, image_input_file, image_output_file): + def process_image(self, + image_input_file, + image_output_file, + file_type, + quality, + compressing, + optimize, + resize = None, + watermark = None, + font_size = 2, + grayscale = False, + brightness = None, + contrast = None, + dict_for_exif = None, + gps = None, + copy_exif = False): + # 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) + image_name = os.path.basename(image_output_file) # for date adjustment - if self.settings["resize"] != False: + # Resize + if resize is not None: processed_img = self.image_processor.resize_image( - image = processed_img, percent = self.settings["resize"] + image=processed_img, percent=resize ) - if self.settings["watermark"] != False: - processed_img = self.image_processor.add_watermark(processed_img, self.settings["watermark"], int(self.settings["font_size"])) - if self.settings["grayscale"] != False: # There is a problem, if we first to grayscale and then watermark it braeks + + # 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) - if self.settings["brightness"] != False: # Does the order of brightness and contrast matter? - processed_img = self.image_processor.change_brightness(processed_img, self.settings["brightness"]) - if self.settings["contrast"] != False: # Does the order of brightness and contrast matter? - processed_img = self.image_processor.change_contrast(processed_img, self.settings["contrast"]) - if self.settings["own_exif"] != False: - selected_exif = self.selected_exif - if "date_time_original" in self.selected_exif: + # 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_data = self.exif_handler.build_exif_dict(selected_exif, self.image_processor.get_image_size(processed_img)) - if self.settings["gps"] != False: - latitude = float(self.settings["gps"][0]) - longitude = float(self.settings["gps"][1]) - exif_data = self.exif_handler.add_geolocation_to_exif(exif_data, latitude, longitude) + exif_piexif_format = self.exif_handler.build_exif_dict( + selected_exif, self.image_processor.get_image_size(processed_img) + ) - elif self.settings["copy_exif"] == True: - # When copying exif from original, make sure to change Piexel X & Y Dimension to fit new size + # 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_data = og_exif + exif_piexif_format = og_exif except Exception: - # If an error happends it is because the picture does not have exif data print("Copying EXIF data selected, but no EXIF data is available in the original image file.") - exif_data = None - elif self.settings["copy_exif"] == False: - exif_data = None + # Save the processed image self.image_processor.save_image( image = processed_img, path = image_output_file, - exif_data = exif_data, - file_type = self.settings["file_format"], - jpg_quality = self.settings["jpg_quality"], - png_compressing = self.settings["png_compression"], - optimize = self.settings["optimize"] + piexif_exif_data = exif_piexif_format, + file_type = file_type, + jpg_quality = quality, + png_compressing = compressing, + optimize = optimize ) - - def name_images(self, base_name, current_image, total_images, invert): - """"Returns name, combination of base_name and ending number.""" - total_digits = len(str(total_images)) - if invert: - ending_number = total_images - (current_image - 1) - else: - ending_number = current_image - ending = f"{ending_number:0{total_digits}}" - return f"{base_name}_{ending}" - -if __name__ == "__main__": - print("Please load OPTIMA35 into the ui class...") - exit()