Add support for modern image formats (WebP and AVIF) and implement image conversion commands
This commit is contained in:
parent
7128f19b9e
commit
477bb753ae
15 changed files with 629 additions and 93 deletions
|
|
@ -12,6 +12,7 @@ from django.conf import settings
|
|||
from django.core.files.base import ContentFile
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.core.management.base import CommandParser
|
||||
from PIL import Image
|
||||
|
||||
from twitch.models import DropBenefit
|
||||
from twitch.models import DropCampaign
|
||||
|
|
@ -245,10 +246,51 @@ class Command(BaseCommand):
|
|||
# Save the image to the FileField
|
||||
if hasattr(file_field, "save"):
|
||||
file_field.save(file_name, ContentFile(response.content), save=True)
|
||||
|
||||
# Auto-convert to WebP and AVIF
|
||||
self._convert_to_modern_formats(file_field.path)
|
||||
|
||||
return "downloaded"
|
||||
|
||||
return "failed"
|
||||
|
||||
def _convert_to_modern_formats(self, image_path: str) -> None:
|
||||
"""Convert downloaded image to WebP and AVIF formats.
|
||||
|
||||
Args:
|
||||
image_path: Absolute path to the downloaded image file
|
||||
"""
|
||||
try:
|
||||
source_path = Path(image_path)
|
||||
if not source_path.exists() or source_path.suffix.lower() not in {".jpg", ".jpeg", ".png"}:
|
||||
return
|
||||
|
||||
base_path = source_path.with_suffix("")
|
||||
webp_path = base_path.with_suffix(".webp")
|
||||
avif_path = base_path.with_suffix(".avif")
|
||||
|
||||
with Image.open(source_path) as img:
|
||||
# Convert to RGB if needed
|
||||
if img.mode in {"RGBA", "LA"} or (img.mode == "P" and "transparency" in img.info):
|
||||
background = Image.new("RGB", img.size, (255, 255, 255))
|
||||
rgba_img = img.convert("RGBA") if img.mode == "P" else img
|
||||
background.paste(rgba_img, mask=rgba_img.split()[-1] if rgba_img.mode in {"RGBA", "LA"} else None)
|
||||
rgb_img = background
|
||||
elif img.mode != "RGB":
|
||||
rgb_img = img.convert("RGB")
|
||||
else:
|
||||
rgb_img = img
|
||||
|
||||
# Save WebP
|
||||
rgb_img.save(webp_path, "WEBP", quality=85, method=6)
|
||||
|
||||
# Save AVIF
|
||||
rgb_img.save(avif_path, "AVIF", quality=85, speed=4)
|
||||
|
||||
except (OSError, ValueError) as e:
|
||||
# Don't fail the download if conversion fails
|
||||
self.stdout.write(self.style.WARNING(f"Failed to convert {image_path}: {e}"))
|
||||
|
||||
def _merge_stats(self, total: dict[str, int], new: dict[str, int]) -> None:
|
||||
"""Merge statistics from a single model into the total stats."""
|
||||
for key in ["total", "downloaded", "skipped", "failed", "placeholders_404"]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue