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
artifacts: true
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
- python3 -m pip install build
- python3 -m build

View file

@ -1,5 +1,10 @@
# 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.2: Bug fixes
- Fixed missing lens in meta data

View file

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

View file

@ -22,83 +22,124 @@ class OptimaManager:
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
def _process_image(
self,
image_input_file: str,
resize: int = None,
watermark: str = None,
font_size: int = 2,
grayscale: bool = False,
brightness: float = None,
contrast: float = None
):
# Restructured by ChatGPT, but had to fix bugs
img = self.image_processor.open_image(image_input_file)
# Apply transformations
if resize is not None:
processed_img = self.image_processor.resize_image(
image=processed_img, percent = resize
)
# Watermark
print("Resize")
img = self.image_processor.resize_image(img, percent=resize)
if watermark is not None:
processed_img = self.image_processor.add_watermark(
processed_img, watermark, int(font_size)
)
# Grayscale
print("Watermark")
img = self.image_processor.add_watermark(img, watermark, font_size)
if grayscale:
processed_img = self.image_processor.grayscale(processed_img)
# Brightness
print("Grayscale")
img = self.image_processor.grayscale(img)
if brightness is not None:
processed_img = self.image_processor.change_brightness(
processed_img, brightness
)
# Contrast
print("Brightness")
img = self.image_processor.change_brightness(img, brightness)
if contrast is not None:
processed_img = self.image_processor.change_contrast(
processed_img, contrast
)
print("Contrast")
img = self.image_processor.change_contrast(img, contrast)
return img
# 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
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:
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)
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
def process_and_save_image(
self,
image_input_file: str,
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.
Args:
image_input_file (str): Path to the input image file.
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.
Returns:
None
"""
# Restructured by ChatGPT
processed_img = self._process_image(
image_input_file,
resize,
watermark,
font_size,
grayscale,
brightness,
contrast,
)
# 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)
# Handle EXIF metadata
exif_piexif_format = self._handle_exif(
image = processed_img,
file_name = image_output_file,
dict_for_exif = dict_for_exif,
gps = gps,
copy_exif = copy_exif
)
# 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
# Save the image
self.image_processor.save_image(
image = processed_img,
path = image_output_file,
@ -106,12 +147,59 @@ class OptimaManager:
file_type = file_type,
jpg_quality = quality,
png_compressing = compressing,
optimize = optimize
optimize = optimize,
)
def process_image_object(
self,
image_input_file: str,
resize: int = None,
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.
Args:
image_input_file (str): Path to the input image file.
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. Defaults to None.
contrast (float, optional): Adjust contrast. Defaults to None.
Returns:
Image: The processed image object.
"""
# Restructured by ChatGPT
processed_img = self._process_image(
image_input_file,
resize,
watermark,
font_size,
grayscale,
brightness,
contrast,
)
else:
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))
img = self.image_processor.open_image(image_path)
selected_exif = exif_dict