Fix IOError with some image modes in photo resize

This fixes image compression with mode "P" (potentially others) which is necessary as the server has erroneous alpha color with some types of images (mode "P" for example). This also properly applies the background argument that may be passed to _resize_photo_if_needed by always compressing images with alpha regardless of whether the server will compress the image for us.
This commit is contained in:
Nick80835 2025-01-12 18:11:46 -05:00 committed by Lonami
parent 494b20db2d
commit b9aafa3441

View File

@ -67,24 +67,31 @@ def _resize_photo_if_needed(
except KeyError: except KeyError:
kwargs = {} kwargs = {}
# Check if image is within acceptable bounds, if so, check if the image is at or below 10 MB, or assume it isn't if size is None or 0 if image.mode == 'RGB':
if image.width <= width and image.height <= height and (before <= 10000000 if before else False): # Check if image is within acceptable bounds, if so, check if the image is at or below 10 MB, or assume it isn't if size is None or 0
return file if image.width <= width and image.height <= height and (before <= 10000000 if before else False):
return file
image.thumbnail((width, height), PIL.Image.LANCZOS) # If the image is already RGB, don't convert it
# certain modes such as 'P' have no alpha index but can't be saved as JPEG directly
alpha_index = image.mode.find('A') image.thumbnail((width, height), PIL.Image.LANCZOS)
if alpha_index == -1:
# If the image mode doesn't have alpha
# channel then don't bother masking it away.
result = image result = image
else: else:
# We could save the resized image with the original format, but # We could save the resized image with the original format, but
# JPEG often compresses better -> smaller size -> faster upload # JPEG often compresses better -> smaller size -> faster upload
# We need to mask away the alpha channel ([3]), since otherwise # We need to mask away the alpha channel ([3]), since otherwise
# IOError is raised when trying to save alpha channels in JPEG. # IOError is raised when trying to save alpha channels in JPEG.
image.thumbnail((width, height), PIL.Image.LANCZOS)
result = PIL.Image.new('RGB', image.size, background) result = PIL.Image.new('RGB', image.size, background)
result.paste(image, mask=image.split()[alpha_index]) mask = None
if image.has_transparency_data:
if image.mode == 'RGBA':
mask = image.getchannel('A')
else:
mask = image.convert('RGBA').getchannel('A')
result.paste(image, mask=mask)
buffer = io.BytesIO() buffer = io.BytesIO()
result.save(buffer, 'JPEG', progressive=True, **kwargs) result.save(buffer, 'JPEG', progressive=True, **kwargs)