A 20480x13312 upscale is past Pillow's pixel limit, so its card image failed and the catch-all fallback served the 324 MB original as the thumbnail: the gallery and the AI workbench decoded it every time. - A picture past the limit is shrunk once by a child process (huge_picture.py, low priority, one at a time) and cached; a card is never a large original, one with no card image gets an SVG with its size. - /anomalous/output_preview gives the viewers the picture or a cached 4096 px copy of a very large one; the viewer (moved to ui_gallery_viewer.js), the image workbench's stage and the AI pages' larger pictures use it, with a note and "Open the original". - The listing carries each file's size (and big ones' pixel size); such a card says "Very large". - The browser-side PNG metadata read stops at the image data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
22 lines
974 B
Python
22 lines
974 B
Python
"""Run by media_routes.py as a child process: a smaller WebP of a picture too large to decode
|
|
inside ComfyUI (past Pillow's pixel limit), so the memory it takes goes back when it ends.
|
|
Arguments: the picture, the WebP to write, the longest edge, the most pixels it may decode."""
|
|
|
|
import sys
|
|
|
|
from PIL import Image, ImageOps
|
|
|
|
|
|
def shrink(source, target, edge, most_pixels):
|
|
Image.MAX_IMAGE_PIXELS = most_pixels
|
|
with Image.open(source) as image:
|
|
image.thumbnail((edge, edge), Image.Resampling.LANCZOS) # a JPEG decodes at a fraction; others whole, once
|
|
image = ImageOps.exif_transpose(image) # on the small one: turning the whole picture would copy it
|
|
if image.mode not in ('RGB', 'RGBA'):
|
|
image = image.convert('RGBA' if 'transparency' in image.info else 'RGB')
|
|
image.save(target, format='WEBP', quality=84, method=4)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
shrink(sys.argv[1], sys.argv[2], int(sys.argv[3]), int(sys.argv[4]))
|