Render photos individually, optimize gallery images, and prune old releases
This commit is contained in:
+15
-2
@@ -22,6 +22,8 @@ from posts import parse_upload
|
||||
|
||||
register_heif_opener()
|
||||
Image.MAX_IMAGE_PIXELS = 60_000_000
|
||||
GALLERY_MAX_EDGE = 1600
|
||||
GALLERY_MAX_BYTES = 300 * 1024
|
||||
warnings.simplefilter("error", Image.DecompressionBombWarning)
|
||||
|
||||
|
||||
@@ -47,7 +49,7 @@ def web_image(raw, destination):
|
||||
if original.format not in {"JPEG", "PNG", "WEBP", "HEIF"}:
|
||||
raise ValueError("Use JPEG, PNG, WebP, or HEIC photos")
|
||||
image = ImageOps.exif_transpose(original)
|
||||
image.thumbnail((2560, 2560), Image.Resampling.LANCZOS)
|
||||
image.thumbnail((GALLERY_MAX_EDGE, GALLERY_MAX_EDGE), Image.Resampling.LANCZOS)
|
||||
if image.info.get("icc_profile"):
|
||||
image = ImageCms.profileToProfile(
|
||||
image, ImageCms.ImageCmsProfile(io.BytesIO(image.info["icc_profile"])),
|
||||
@@ -63,7 +65,18 @@ def web_image(raw, destination):
|
||||
# Copy pixels only; no EXIF, GPS, XMP, comments, or original profile.
|
||||
clean = Image.new("RGB", image.size)
|
||||
clean.paste(image)
|
||||
clean.save(destination, "JPEG", quality=88, optimize=True)
|
||||
# Keep a useful display size and moderate JPEG quality, even for grainy photos.
|
||||
# If quality alone cannot meet the budget, reduce dimensions instead of
|
||||
# introducing severe compression artifacts. Originals remain untouched.
|
||||
while True:
|
||||
for quality in (82, 78, 74):
|
||||
output = io.BytesIO()
|
||||
clean.save(output, "JPEG", quality=quality, optimize=True, progressive=True)
|
||||
if output.tell() <= GALLERY_MAX_BYTES:
|
||||
Path(destination).write_bytes(output.getvalue())
|
||||
return
|
||||
clean.thumbnail((max(1, int(clean.width * 0.85)), max(1, int(clean.height * 0.85))),
|
||||
Image.Resampling.LANCZOS)
|
||||
|
||||
|
||||
def create_app(data_dir=None, token=None):
|
||||
|
||||
Reference in New Issue
Block a user