moving image handler and utility file to new folder

This commit is contained in:
Mr Finchum 2024-12-28 00:28:37 +01:00
parent 3e8ec921ab
commit 5c61ff0587
3 changed files with 162 additions and 0 deletions

0
utils/__init__.py Normal file
View file

115
utils/image_handler.py Normal file
View file

@ -0,0 +1,115 @@
from PIL import Image, ImageDraw, ImageFont, ImageEnhance
import piexif
import time
class ImageProcessor:
"""Functions using pillow are in here."""
def __init__(self):
pass
def open_image(self, path):
"""Open an image from path, returns image object."""
return Image.open(path)
def get_image_size(self, image):
"""Simply get image size."""
return image.size
def grayscale(self, image):
"""Change to grayscale"""
return image.convert("L")
def change_contrast(self, image, change):
enhancer = ImageEnhance.Contrast(image)
new_img = enhancer.enhance(1 + (change/100))
return new_img
def change_brightness(self, image, change):
enhancer = ImageEnhance.Brightness(image)
new_img = enhancer.enhance(1 + (change/100))
return new_img
def resize_image(self, image, percent, resample = True):
"""Resize an image by giving a percent."""
new_size = tuple(int(x * (percent / 100)) for x in image.size)
if resample:
resized_image = image.resize(new_size)
else:
resized_image = image.resize((new_size),resample=Image.Resampling.NEAREST)
return resized_image
def add_watermark(self, image, text, font_size_scale = 70):
drawer = ImageDraw.Draw(image)
imagewidth, imageheight = image.size
margin = (imageheight / 100 ) * 2 # margin dynamic, 2% of image size
font_size = imagewidth / font_size_scale # Scaling the font size
try: # Try loading front, if notaviable return unmodified image
font = ImageFont.truetype("OpenDyslexic3-Regular.ttf", font_size)
except:
print("Error loading font for watermark, please ensure font is installed...\n")
time.sleep(0.3)
return image
c, w, textwidth, textheight, = drawer.textbbox(xy = (0, 0), text = text, font = font) # Getting text size, only need the last two values
x = imagewidth - textwidth - margin
y = imageheight - textheight - margin
drawer.text((x, y), text, font = font)
return image
def save_image(self, image, path, file_type, jpg_quality, png_compressing, optimize, exif_data = None):
# partly optimized by chatGPT
"""
Save an image to the specified path with optional EXIF data and optimization.
"""
file_type = file_type.lower()
save_params = {"optimize": optimize}
# Add file-specific parameters
if file_type == "jpg":
save_params["quality"] = jpg_quality
elif file_type == "png":
save_params["compress_level"] = png_compressing
elif file_type not in ["webp", "jpg", "png"]:
input(f"Type: {file_type} is not supported. Press Enter to continue...")
return
# Add EXIF data if available
if exif_data is not None:
save_params["exif"] = piexif.dump(exif_data)
if file_type == "webp":
print("File format webp does not support all exif features, some information might get lost...\n")
time.sleep(0.1)
try:
image.save(f"{path}.{file_type}", **save_params)
except Exception as e:
print(f"Failed to save image: {e}")
class ExifHandler:
"""Function using piexif are here."""
def __init__(self):
pass
def get_exif_info(self, image):
return(piexif.load(image.info['exif']))
def build_exif_dict(self, user_data, imagesize):
"""Build a piexif-compatible EXIF dictionary from user data."""
# Mostly made by ChatGPT, some adjustment
zeroth_ifd = {
piexif.ImageIFD.Make: user_data["make"],
piexif.ImageIFD.Model: user_data["model"],
piexif.ImageIFD.Software: user_data["software"],
piexif.ImageIFD.Copyright: user_data["copyright_info"],
piexif.ImageIFD.Artist: user_data["artist"],
piexif.ImageIFD.ImageDescription: user_data["image_description"],
piexif.ImageIFD.XResolution: (72, 1),
piexif.ImageIFD.YResolution: (72, 1),
}
exif_ifd = {
piexif.ExifIFD.UserComment: user_data["user_comment"],
piexif.ExifIFD.ISOSpeedRatings: int(user_data["iso"]),
piexif.ExifIFD.PixelXDimension: imagesize[0],
piexif.ExifIFD.PixelYDimension: imagesize[1],
}
if "date_time_original" in user_data:
exif_ifd[piexif.ExifIFD.DateTimeOriginal] = user_data["date_time_original"].encode("utf-8")
return {"0th": zeroth_ifd, "Exif": exif_ifd}

47
utils/utility.py Normal file
View file

@ -0,0 +1,47 @@
import yaml
class Utilities:
def __init__(self):
pass
def read_yaml(self, yaml_file):
try:
with open(yaml_file, "r") as file:
data = yaml.safe_load(file)
return data
except (FileNotFoundError, PermissionError) as e:
print(f"Error loading settings file: {e}")
return
def write_yaml(self, yaml_file, data):
try:
with open(yaml_file, "w") as file:
yaml.dump(data, file)
except PermissionError as e:
print(f"Error saving setings: {e}")
def yes_no(self, str):
"""Ask user y/n question"""
while True:
choice = input(f"{str} (y/n): ")
if choice == "y":
return True
elif choice == "n":
return False
else:
print("Not a valid option, try again.")
def progress_bar(self, current, total, barsize = 50):
if current > total:
print("\033[91mThis bar has exceeded its limits!\033[0m Maybe the current value needs some restraint?")
print(f"{(current - total) * '\033[92mHonk, Honk!\033[0m '}")
return
progress = int((barsize / total) * current)
rest = barsize - progress
if rest <= 2: rest = 0
# Determine the number of digits in total
total_digits = len(str(total))
# Format current with leading zeros
current_formatted = f"{current:0{total_digits}}"
print(f"{current_formatted}|{progress * '-'}>{rest * ' '}|{total}", end="\r")
if current == total: print("")