prosberry/generate_responsive_images.py

74 lines
2.9 KiB
Python

import os
from PIL import Image
# Project root directory (where this script is located)
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
IMAGES_DIR = os.path.join(PROJECT_ROOT, 'assets', 'images')
# Define images and their desired responsive widths
# Each tuple: (original_filename, [list_of_widths_to_generate])
RESPONSIVE_IMAGES_CONFIG = [
('amra.webp', [320, 480, 767, 960]), # Added 320w
('logo.webp', [100, 200, 400]) # Added 100w
]
def generate_responsive_image(image_path, output_width, output_dir, quality=85):
"""
Generates a responsive version of an image with a specified width.
Maintains aspect ratio.
"""
try:
with Image.open(image_path) as img:
# Calculate new height to maintain aspect ratio
original_width, original_height = img.size
if original_width <= output_width:
# If original is smaller or equal, no need to resize down
# We still save it with the new naming convention if it's part of srcset
new_width = original_width
new_height = original_height
else:
new_width = output_width
new_height = int((original_height * new_width) / original_width)
# Resize only if dimensions change
if new_width != original_width or new_height != original_height:
img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
# Construct new filename (e.g., amra-480w.webp)
base_name, ext = os.path.splitext(os.path.basename(image_path))
# Ensure we only take the base name before any existing -<width>w
base_name_clean = base_name.split('-')[0]
new_filename = f"{base_name_clean}-{output_width}w{ext}"
output_path = os.path.join(output_dir, new_filename)
img.save(output_path, format=img.format, quality=quality)
print(f"Generated: {output_path} ({new_width}x{new_height})")
return True
except FileNotFoundError:
print(f"Error: Source image not found at {image_path}")
return False
except Exception as e:
print(f"Error processing {image_path} for width {output_width}: {e}")
return False
def main():
print("Starting responsive image generation...")
if not os.path.exists(IMAGES_DIR):
print(f"Error: Image directory not found at {IMAGES_DIR}")
return
for original_filename, widths in RESPONSIVE_IMAGES_CONFIG:
original_image_path = os.path.join(IMAGES_DIR, original_filename)
if not os.path.exists(original_image_path):
print(f"Warning: Original image {original_filename} not found. Skipping.")
continue
for width in widths:
generate_responsive_image(original_image_path, width, IMAGES_DIR)
print("Responsive image generation complete.")
if __name__ == "__main__":
main()