import sys import os import re import time from datetime import datetime from utils.utility import Utilities from utils.image_handler import ImageProcessor, ExifHandler from ui.main_window import Ui_MainWindow from PySide6 import QtWidgets from PySide6.QtWidgets import ( QMessageBox, QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, QCheckBox, QFileDialog, QHBoxLayout, QSpinBox, ) class Optima35QT6(QMainWindow, Ui_MainWindow): def __init__(self): super(Optima35QT6, self).__init__() self.ui = Ui_MainWindow() self.ui.setupUi(self) self.define_settings() self.setWindowTitle(f"{self.name} v{self.version}") self.define_gui_interaction() def define_gui_interaction(self): self.ui.input_folder_button.clicked.connect(self.browse_input_folder) self.ui.output_folder_button.clicked.connect(self.browse_output_folder) self.ui.start_button.clicked.connect(self.process) def define_settings(self): self.name = "OPTIMA-35" self.version = "0.3.0" self.utilities = Utilities() self.image_processor = ImageProcessor() self.exif_handler = ExifHandler() self.settings = { "input_folder": None, "output_folder": None, "file_format": None, "resize_percentage": False, "contrast_percentage": False, "brightness_percentage": 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 } self.exif_data = None def browse_input_folder(self): folder = QFileDialog.getExistingDirectory(self, "Select Input Folder") if folder: self.ui.input_path.setText(folder) def browse_output_folder(self): folder = QFileDialog.getExistingDirectory(self, "Select Output Folder") if folder: self.ui.output_path.setText(folder) def process(self): self.check_options() if os.path.exists(self.settings["input_folder"]) and os.path.exists(self.settings["output_folder"]): print(self.settings) else: print(self.settings) QMessageBox.warning(self, "Warning", "Input and/or output folder invalid...") return input_folder = self.settings["input_folder"] output_folder = self.settings["output_folder"] image_files = [ f for f in os.listdir(input_folder) if f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")) ] i = 1 for image_file in image_files: input_path = os.path.join(input_folder, image_file) if self.settings["new_file_names"] != False: image_name = self.name_images(self.settings["new_file_names"], i, len(image_files), self.settings["invert_image_order"]) else: image_name = os.path.splitext(image_file)[0] output_path = os.path.join(output_folder, image_name) with self.image_processor.open_image(input_path) as img: processed_img = img if self.settings["resize_percentage"] != False: processed_img = self.image_processor.resize_image( image = processed_img, percent = self.settings["resize_percentage"] ) if self.settings["watermark"] != False: processed_img = self.image_processor.add_watermark(processed_img, self.settings["watermark"]) if self.settings["grayscale"] != False: # There is a problem, if we first to grayscale and then watermark it braeks processed_img = self.image_processor.grayscale(processed_img) if self.settings["brightness_percentage"] != False: # Does the order of brightness and contrast matter? processed_img = self.image_processor.change_brightness(processed_img, self.settings["brightness_percentage"]) if self.settings["contrast_percentage"] != False: # Does the order of brightness and contrast matter? processed_img = self.image_processor.change_contrast(processed_img, self.settings["contrast_percentage"]) if self.settings["copy_exif"] != False: # When copying exif from original, make sure to change Piexel X & Y Dimension to fit new size 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 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 self.image_processor.save_image( image = processed_img, path = output_path, exif_data = exif_data, file_type = self.settings["file_format"], jpg_quality = self.settings["jpg_quality"], png_compressing = self.settings["png_compression"], optimize = False ) self.handle_qprogressbar(i, len(image_files)) i += 1 QMessageBox.information(self, "Information", "Finished") self.ui.progressBar.setValue(0) def handle_qprogressbar(self, current, total): progress = int((100 / total) * current) self.ui.progressBar.setValue(progress) 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}" def check_options(self): try: self.settings["input_folder"] = self.ui.input_path.text() self.settings["output_folder"] = self.ui.output_path.text() self.settings["file_format"] = self.ui.image_type.currentText() self.settings["jpg_quality"] = int(self.ui.jpg_quality_spinBox.text()) self.settings["png_compression"] = int(self.ui.png_quality_spinBox.text()) self.settings["invert_image_order"] = self.ui.revert_checkbox.isChecked() self.settings["grayscale"] = self.ui.grayscale_checkBox.isChecked() self.settings["copy_exif"] = self.ui.copy_exif_checkBox.isChecked() self.settings["own_exif"] = self.ui.exif_checkbox.isChecked() if self.ui.resize_checkbox.isChecked(): self.settings["resize_percentage"] = int(self.ui.resize_spinBox.text()) if self.ui.brightness_checkbox.isChecked(): self.settings["brightness_percentage"] = int(self.ui.brightness_spinBox.text()) if self.ui.contrast_checkbox.isChecked(): self.settings["contrast_percentage"] = int(self.ui.contrast_spinBox.text()) if self.ui.rename_checkbox.isChecked() and self.ui.filename.text() != "": self.settings["new_file_names"] = self.ui.filename.text() if self.ui.watermark_checkbox.isChecked() and self.ui.watermark_lineEdit.text() != "": self.settings["watermark"] = self.ui.watermark_lineEdit.text() except Exception as e: print(f"Whoops: {e}") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) window = Optima35QT6() window.show() app.exec()