Files
ALwrity/lib/optimize_images_for_upload.py
2023-12-21 21:21:09 +05:30

113 lines
3.5 KiB
Python

import sys
import os
import tinify
from PIL import Image
from loguru import logger
from tqdm import tqdm
from dotenv import load_dotenv
#default directory for .env file is the current directory
#if you set .env in different directory, put the directory address load_dotenv("directory_of_.env)
load_dotenv()
# Retrieve Tinyfy API key from environment variable
tinify.key = os.getenv('TINIFY_API_KEY')
# Configure logger
logger.remove()
logger.add(sys.stdout, colorize=True, format="<level>{level}</level>|<green>{file}:{line}:{function}</green>| {message}")
def compress_image(image_path, quality=45, resize=None, preserve_exif=False):
"""
Compress and optionally resize an image, and overwrite the original image.
Args:
image_path (str): Path to the original image.
quality (int): Quality of the output image (1-100).
resize (tuple): Tuple (width, height) to resize image.
preserve_exif (bool): Preserve EXIF data if True.
"""
if not os.path.exists(image_path):
logger.error(f"Image path does not exist: {image_path}")
return
original_size = os.path.getsize(image_path)
try:
with Image.open(image_path) as img:
img_format = img.format
exif = img.info['exif'] if preserve_exif and 'exif' in img.info else None
if resize:
img = img.resize(resize, Image.ANTIALIAS)
img.save(image_path, format=img_format, quality=quality, optimize=True, exif=exif)
compressed_size = os.path.getsize(image_path)
reduction = (1 - (compressed_size / original_size)) * 100
logger.info(f"Compressed {image_path}, Reduction: {reduction:.2f}%")
except Exception as e:
logger.error(f"Error compressing image {image_path}: {e}")
def is_image_file(filename):
"""
Check if a file is an image based on its extension.
Args:
filename (str): Name of the file to check.
Returns:
bool: True if the file is an image, False otherwise.
"""
valid_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
return any(filename.lower().endswith(ext) for ext in valid_extensions)
def convert_to_webp(image_path):
"""
Convert an image to WebP format.
Args:
image_path (str): Path to the original image.
Returns:
str: Path to the WebP image.
"""
if not os.path.exists(image_path):
logger.error(f"Image path does not exist: {image_path}")
return
try:
with Image.open(image_path) as img:
webp_path = os.path.splitext(image_path)[0] + '.webp'
img.save(webp_path, 'WEBP')
logger.info(f"Converted {image_path} to WebP")
return webp_path
except Exception as e:
logger.error(f"Error converting image to WebP: {e}")
def compress_image_tinyfy(image_path):
"""
Compress the image using Tinyfy API.
Args:
image_path (str): Path to the original image.
"""
if not os.path.exists(image_path):
logger.error(f"Image path does not exist: {image_path}")
return
try:
source = tinify.from_file(image_path)
source.to_file(image_path)
logger.info(f"Compressed {image_path} using Tinyfy API")
except tinify.Error as e:
logger.error(f"Tinyfy API error: {e}")
def optimize_image(image_path):
image_path = convert_to_webp(image_path)
compress_image_tinyfy(image_path)
compress_image(image_path)
return image_path