From cb8c11c41676b09fc929272520d105defd9ac8a3 Mon Sep 17 00:00:00 2001 From: Cagri Sarigoz Date: Sat, 31 Jan 2026 12:03:09 +0000 Subject: [PATCH] [charlie] feat: Add AVIF support for smart format optimization --- README.md | 2 +- cloudfront_provider.py | 14 ++++++++++++-- requirements.txt | 3 ++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ceefef5..24b53b0 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Choose between two powerful image delivery platforms: - **🔄 Multi-Provider Support**: Choose between Cloudinary and AWS CloudFront/S3 - **📦 Batch Image Processing**: Download images from URLs and upload to your chosen provider - **🎯 Smart Optimization**: Automatic resizing, quality adjustment, and format conversion -- **🎨 Format Intelligence**: Automatically chooses the best format (JPEG, PNG, WebP) for optimal file size +- **🎨 Format Intelligence**: Automatically chooses the best format (JPEG, PNG, WebP, AVIF) for optimal file size - **⚡ Unique URLs**: Adds timestamps to prevent filename conflicts and ensure cache busting - **🤖 AI Alt Text Generation**: Generate descriptive alt text using AltText.ai API - **🔌 REST API**: HTTP endpoints for programmatic access diff --git a/cloudfront_provider.py b/cloudfront_provider.py index ea1a89f..e8d49fb 100644 --- a/cloudfront_provider.py +++ b/cloudfront_provider.py @@ -20,6 +20,12 @@ from botocore.exceptions import ClientError from PIL import Image + # Optional: enable AVIF read/write support when pillow-avif-plugin is installed + try: + import pillow_avif # noqa: F401 + except Exception: + pass + BOTO3_AVAILABLE = True except ImportError: BOTO3_AVAILABLE = False @@ -129,8 +135,8 @@ def _optimize_image( def _get_best_format( self, img: Image.Image, original_path: str, quality: int = 82 ) -> Tuple[bool, str]: - """Determine the best format (JPEG, PNG, WebP) based on file size""" - formats_to_try = ["JPEG", "PNG", "WEBP"] + """Determine the best format (JPEG, PNG, WebP, AVIF) based on file size""" + formats_to_try = ["JPEG", "PNG", "WEBP", "AVIF"] # Skip testing if the image has transparency and we're considering JPEG has_transparency = img.mode in ("RGBA", "LA") or ( @@ -164,6 +170,10 @@ def _get_best_format( test_img.save(temp_file, format=fmt, optimize=True) elif fmt == "WEBP": test_img.save(temp_file, format=fmt, quality=quality, method=6) + elif fmt == "AVIF": + # AVIF uses a quality parameter similar to WebP. + # pillow-avif-plugin adds support for saving AVIF via Pillow. + test_img.save(temp_file, format=fmt, quality=quality) # Get file size file_size = os.path.getsize(temp_file) diff --git a/requirements.txt b/requirements.txt index dd3adc9..56f0029 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ Werkzeug==3.1.3 requests==2.32.3 pillow==11.2.1 python-dotenv==1.1.0 -cloudinary==1.40.0 \ No newline at end of file +cloudinary==1.40.0 +pillow-avif-plugin>=1.4.0