Moved image handler to optima folder.

This commit is contained in:
Mr Finchum 2025-01-02 15:10:06 +01:00
parent 5ae4c8f9ef
commit 7ef1960ced

View file

@ -1,6 +1,5 @@
from PIL import Image, ImageDraw, ImageFont, ImageEnhance from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import piexif import piexif
import time
from fractions import Fraction from fractions import Fraction
class ImageProcessor: class ImageProcessor:
@ -21,11 +20,13 @@ class ImageProcessor:
return image.convert("L") return image.convert("L")
def change_contrast(self, image, change): def change_contrast(self, image, change):
"""Change contrast by percent."""
enhancer = ImageEnhance.Contrast(image) enhancer = ImageEnhance.Contrast(image)
new_img = enhancer.enhance(1 + (change/100)) new_img = enhancer.enhance(1 + (change/100))
return new_img return new_img
def change_brightness(self, image, change): def change_brightness(self, image, change):
"""Changes brightness by percent"""
enhancer = ImageEnhance.Brightness(image) enhancer = ImageEnhance.Brightness(image)
new_img = enhancer.enhance(1 + (change/100)) new_img = enhancer.enhance(1 + (change/100))
return new_img return new_img
@ -40,7 +41,7 @@ class ImageProcessor:
return resized_image return resized_image
def add_watermark(self, image, text, font_size_percentage): def add_watermark(self, image, text, font_size_percentage):
# Still not happy about this function.. """Addes a watermark to the image using default os font."""
drawer = ImageDraw.Draw(image) drawer = ImageDraw.Draw(image)
imagewidth, imageheight = image.size imagewidth, imageheight = image.size
margin = (imageheight / 100 ) * 2 # margin dynamic, 2% of image size margin = (imageheight / 100 ) * 2 # margin dynamic, 2% of image size
@ -50,7 +51,6 @@ class ImageProcessor:
font = ImageFont.load_default(font_size) font = ImageFont.load_default(font_size)
except Exception as e: except Exception as e:
print(f"Error {e}\nloading font for watermark, please ensure font is installed...\n") print(f"Error {e}\nloading font for watermark, please ensure font is installed...\n")
time.sleep(0.1)
return image return image
c, w, textwidth, textheight, = drawer.textbbox(xy = (0, 0), text = text, font = font) # Getting text size, only need the last two values c, w, textwidth, textheight, = drawer.textbbox(xy = (0, 0), text = text, font = font) # Getting text size, only need the last two values
@ -67,12 +67,11 @@ class ImageProcessor:
return image return image
def save_image(self, image, path, file_type, jpg_quality, png_compressing, optimize, exif_data): def save_image(self, image, path, file_type, jpg_quality, png_compressing, optimize, piexif_exif_data):
# partly optimized by chatGPT # partly optimized by chatGPT
""" """
Save an image to the specified path with optional EXIF data and optimization. Save an image to the specified path with optional EXIF data.
""" """
file_type = file_type.lower()
save_params = {"optimize": optimize} save_params = {"optimize": optimize}
# Add file-specific parameters # Add file-specific parameters
if file_type == "jpg" or "webp": if file_type == "jpg" or "webp":
@ -83,11 +82,10 @@ class ImageProcessor:
input(f"Type: {file_type} is not supported. Press Enter to continue...") input(f"Type: {file_type} is not supported. Press Enter to continue...")
return return
# Add EXIF data if available # Add EXIF data if available
if exif_data is not None: if piexif_exif_data is not None:
save_params["exif"] = piexif.dump(exif_data) save_params["exif"] = piexif.dump(piexif_exif_data)
if file_type == "webp": if file_type == "webp":
print("File format webp does not support all exif features, some information might get lost...\n") print("File format webp does not support all exif features, some information might get lost...\n")
time.sleep(0.1)
try: try:
image.save(f"{path}.{file_type}", **save_params) image.save(f"{path}.{file_type}", **save_params)
except Exception as e: except Exception as e:
@ -102,7 +100,7 @@ class ExifHandler:
return(piexif.load(image.info['exif'])) return(piexif.load(image.info['exif']))
def build_exif_dict(self, user_data, imagesize): def build_exif_dict(self, user_data, imagesize):
"""Build a piexif-compatible EXIF dictionary from user data.""" """Build a piexif-compatible EXIF dictionary from a dicts."""
# Mostly made by ChatGPT, some adjustment # Mostly made by ChatGPT, some adjustment
zeroth_ifd = { zeroth_ifd = {
piexif.ImageIFD.Make: user_data["make"].encode("utf-8"), piexif.ImageIFD.Make: user_data["make"].encode("utf-8"),
@ -125,7 +123,7 @@ class ExifHandler:
return {"0th": zeroth_ifd, "Exif": exif_ifd} return {"0th": zeroth_ifd, "Exif": exif_ifd}
def deg_to_dms(self, decimal_coordinate, cardinal_directions): def _deg_to_dms(self, decimal_coordinate, cardinal_directions):
""" """
This function converts decimal coordinates into the DMS (degrees, minutes and seconds) format. This function converts decimal coordinates into the DMS (degrees, minutes and seconds) format.
It also determines the cardinal direction of the coordinates. It also determines the cardinal direction of the coordinates.
@ -147,7 +145,7 @@ class ExifHandler:
seconds = Fraction((decimal_minutes - minutes) * 60).limit_denominator(100) seconds = Fraction((decimal_minutes - minutes) * 60).limit_denominator(100)
return degrees, minutes, seconds, compass_direction return degrees, minutes, seconds, compass_direction
def dms_to_exif_format(self, dms_degrees, dms_minutes, dms_seconds): def _dms_to_exif_format(self, dms_degrees, dms_minutes, dms_seconds):
""" """
This function converts DMS (degrees, minutes and seconds) to values that can This function converts DMS (degrees, minutes and seconds) to values that can
be used with the EXIF (Exchangeable Image File Format). be used with the EXIF (Exchangeable Image File Format).
@ -176,12 +174,12 @@ class ExifHandler:
:param longitude: the eastwest position coordinate :param longitude: the eastwest position coordinate
""" """
# converts the latitude and longitude coordinates to DMS # converts the latitude and longitude coordinates to DMS
latitude_dms = self.deg_to_dms(latitude, ["S", "N"]) latitude_dms = self._deg_to_dms(latitude, ["S", "N"])
longitude_dms = self.deg_to_dms(longitude, ["W", "E"]) longitude_dms = self._deg_to_dms(longitude, ["W", "E"])
# convert the DMS values to EXIF values # convert the DMS values to EXIF values
exif_latitude = self.dms_to_exif_format(latitude_dms[0], latitude_dms[1], latitude_dms[2]) exif_latitude = self._dms_to_exif_format(latitude_dms[0], latitude_dms[1], latitude_dms[2])
exif_longitude = self.dms_to_exif_format(longitude_dms[0], longitude_dms[1], longitude_dms[2]) exif_longitude = self._dms_to_exif_format(longitude_dms[0], longitude_dms[1], longitude_dms[2])
try: try:
# https://exiftool.org/TagNames/GPS.html # https://exiftool.org/TagNames/GPS.html