Release candidate

This commit is contained in:
Mr Finchum 2025-01-27 18:56:11 +01:00
parent 8f539d4097
commit 2b35cbc48b
4 changed files with 175 additions and 82 deletions

View file

@ -26,7 +26,7 @@ build:
- job: gitversion - job: gitversion
artifacts: true artifacts: true
script: script:
- sed -i "s/0.0.1/${GitVersion_MajorMinorPatch}/" src/optima35/__init__.py - sed -i "s/1.0.0/${GitVersion_MajorMinorPatch}/" src/optima35/__init__.py
- cat src/optima35/__init__.py - cat src/optima35/__init__.py
- python3 -m pip install build - python3 -m pip install build
- python3 -m build - python3 -m build

View file

@ -1,5 +1,10 @@
# Changelog # Changelog
## 1.0.0-rc:
### Refactoring
- Added function descriptions for better clarity and maintainability.
- Introduced guidelines for each function, defining objectives and expected behavior.
## 0.12.x ## 0.12.x
### 0.12.2: Bug fixes ### 0.12.2: Bug fixes
- Fixed missing lens in meta data - Fixed missing lens in meta data

View file

@ -1 +1 @@
__version__ = "0.0.1" __version__ = "1.0.0"

View file

@ -22,96 +22,184 @@ class OptimaManager:
data_for_exif["date_time_original"] = new_time.strftime("%Y:%m:%d %H:%M:%S") data_for_exif["date_time_original"] = new_time.strftime("%Y:%m:%d %H:%M:%S")
return data_for_exif return data_for_exif
def process_image(self, # TODO: split into two classes, one for modification for one saving.. def _process_image(
image_input_file, self,
image_output_file, image_input_file: str,
file_type = "jpg", resize: int = None,
quality = 90, watermark: str = None,
compressing = 6, font_size: int = 2,
optimize = False, grayscale: bool = False,
resize = None, brightness: float = None,
watermark = None, contrast: float = None
font_size = 2, ):
grayscale = False, # Restructured by ChatGPT, but had to fix bugs
brightness = None, img = self.image_processor.open_image(image_input_file)
contrast = None, # Apply transformations
dict_for_exif = None, if resize is not None:
gps = None, print("Resize")
copy_exif = False, img = self.image_processor.resize_image(img, percent=resize)
save = True): if watermark is not None:
# Partly optimized by ChatGPT print("Watermark")
# Open the image file img = self.image_processor.add_watermark(img, watermark, font_size)
with self.image_processor.open_image(image_input_file) as img: if grayscale:
processed_img = img print("Grayscale")
image_name = os.path.basename(image_output_file) # for date adjustment img = self.image_processor.grayscale(img)
# Resize if brightness is not None:
if resize is not None: print("Brightness")
processed_img = self.image_processor.resize_image( img = self.image_processor.change_brightness(img, brightness)
image=processed_img, percent = resize if contrast is not None:
print("Contrast")
img = self.image_processor.change_contrast(img, contrast)
return img
def _handle_exif(
self,
image,
file_name,
dict_for_exif: dict = None,
gps: tuple[float, float] = None,
copy_exif: bool = False
):
# Restructured by ChatGPT, but had to fix bugs
# Build or copy EXIF data
if dict_for_exif:
if "date_time_original" in dict_for_exif:
dict_for_exif = self.modify_timestamp_in_exif(dict_for_exif, file_name)
exif_data = self.exif_handler.build_exif_bytes(
dict_for_exif, self.image_processor.get_image_size(image)
)
if gps:
exif_data = self.exif_handler.add_geolocation_to_exif(
exif_data, gps[0], gps[1]
) )
elif copy_exif:
exif_data = self.exif_handler.get_exif_info(image)
else:
exif_data = None
return exif_data
# Watermark def process_and_save_image(
if watermark is not None: self,
processed_img = self.image_processor.add_watermark( image_input_file: str,
processed_img, watermark, int(font_size) image_output_file: str,
) file_type: str = "jpg",
quality: int = 90,
compressing: int = 6,
optimize: bool = False,
resize: int = None,
watermark: str = None,
font_size: int = 2,
grayscale: bool = False,
brightness: float = None,
contrast: float = None,
dict_for_exif: dict = None,
gps: tuple[float, float] = None,
copy_exif: bool = False
) -> None:
"""
Processes an image with the given parameters and saves the output to a file.
# Grayscale Args:
if grayscale: image_input_file (str): Path to the input image file.
processed_img = self.image_processor.grayscale(processed_img) image_output_file (str): Path to save the processed image.
file_type (str): Output image format ('jpg', 'png'). Defaults to 'jpg'.
quality (int): JPEG quality (1-100). Defaults to 90.
compressing (int): PNG compression level (0-9). Defaults to 6.
optimize (bool): Optimize image for smaller file size. Defaults to False.
resize (int, optional): Resize percentage. Defaults to None.
watermark (str, optional): Watermark text to add. Defaults to None.
font_size (int): Font size for the watermark. Defaults to 2.
grayscale (bool): Convert image to grayscale. Defaults to False.
brightness (float, optional): Adjust brightness (e.g., 1.2 for 20% brighter). Defaults to None.
contrast (float, optional): Adjust contrast (e.g., 1.5 for 50% higher contrast). Defaults to None.
dict_for_exif (dict, optional): EXIF metadata to insert. Defaults to None.
gps (tuple[float, float], optional): GPS coordinates (latitude, longitude). Defaults to None.
copy_exif (bool): Copy EXIF metadata from the input image. Defaults to False.
# Brightness Returns:
if brightness is not None: None
processed_img = self.image_processor.change_brightness( """
processed_img, brightness # Restructured by ChatGPT
) processed_img = self._process_image(
image_input_file,
resize,
watermark,
font_size,
grayscale,
brightness,
contrast,
)
# Contrast # Handle EXIF metadata
if contrast is not None: exif_piexif_format = self._handle_exif(
processed_img = self.image_processor.change_contrast( image = processed_img,
processed_img, contrast file_name = image_output_file,
) dict_for_exif = dict_for_exif,
gps = gps,
copy_exif = copy_exif
)
# EXIF data handling # Save the image
exif_piexif_format = None self.image_processor.save_image(
if dict_for_exif: # todo: maybe move to ui and only accept complete exif dicts.. image = processed_img,
selected_exif = dict_for_exif path = image_output_file,
if "date_time_original" in dict_for_exif: piexif_exif_data = exif_piexif_format,
selected_exif = self.modify_timestamp_in_exif(selected_exif, image_name) file_type = file_type,
exif_piexif_format = self.exif_handler.build_exif_bytes( jpg_quality = quality,
selected_exif, self.image_processor.get_image_size(processed_img) png_compressing = compressing,
) optimize = optimize,
)
# GPS data def process_image_object(
if gps is not None: self,
latitude = float(gps[0]) image_input_file: str,
longitude = float(gps[1]) resize: int = None,
exif_piexif_format = self.exif_handler.add_geolocation_to_exif(exif_piexif_format, latitude, longitude) watermark: str = None,
font_size: int = 2,
grayscale: bool = False,
brightness: float = None,
contrast: float = None
):
"""
Processes an image with the given parameters and returns the modified image object.
# Copy EXIF data if selected, and ensure size is correct in exif data Args:
elif copy_exif: image_input_file (str): Path to the input image file.
try: resize (int, optional): Resize percentage. Defaults to None.
og_exif = self.exif_handler.get_exif_info(img) watermark (str, optional): Watermark text to add. Defaults to None.
og_exif["Exif"][40962], og_exif["Exif"][40963] = self.image_processor.get_image_size(processed_img) font_size (int): Font size for the watermark. Defaults to 2.
exif_piexif_format = og_exif grayscale (bool): Convert image to grayscale. Defaults to False.
except Exception: brightness (float, optional): Adjust brightness. Defaults to None.
print("Copying EXIF data selected, but no EXIF data is available in the original image file.") contrast (float, optional): Adjust contrast. Defaults to None.
if save: Returns:
# Save the processed image Image: The processed image object.
self.image_processor.save_image( """
image = processed_img, # Restructured by ChatGPT
path = image_output_file, processed_img = self._process_image(
piexif_exif_data = exif_piexif_format, image_input_file,
file_type = file_type, resize,
jpg_quality = quality, watermark,
png_compressing = compressing, font_size,
optimize = optimize grayscale,
) brightness,
else: contrast,
return self.image_processor.convert_pil_to_qtimage(processed_img) )
return self.image_processor.convert_pil_to_qtimage(processed_img)
def insert_dict_to_image(self, exif_dict, image_path, gps = None): def insert_exif_to_image(self, exif_dict: dict, image_path: str, gps: tuple[float, float] = None) -> None:
"""
Inserts EXIF metadata into an image.
Args:
exif_data (dict): A dictionary containing EXIF metadata as key-value pairs (e.g., strings, integers).
image_path (str): Absolute path to the target image file.
gps (tuple[float, float], optional): GPS coordinates as a tuple (latitude, longitude). Defaults to None.
Returns:
None: The function modifies the image file in place.
"""
# Restructured by ChatGPT
image_name, ending = os.path.splitext(os.path.basename(image_path)) image_name, ending = os.path.splitext(os.path.basename(image_path))
img = self.image_processor.open_image(image_path) img = self.image_processor.open_image(image_path)
selected_exif = exif_dict selected_exif = exif_dict