|
3 | 3 | import io
|
4 | 4 |
|
5 | 5 | from nxtools import logging
|
6 |
| -from PIL import Image |
| 6 | +from PIL import Image, UnidentifiedImageError |
7 | 7 | from starlette.concurrency import run_in_threadpool
|
8 | 8 |
|
9 | 9 |
|
@@ -87,41 +87,46 @@ async def process_thumbnail(
|
87 | 87 | """
|
88 | 88 |
|
89 | 89 | def process_image():
|
90 |
| - with Image.open(io.BytesIO(image_bytes)) as img: |
91 |
| - target_format = format or img.format or "JPEG" |
92 |
| - |
93 |
| - # Ensure that we have valid dimensions |
94 |
| - if size == (None, None): |
95 |
| - raise ValueError("Both width and height cannot be None") |
96 |
| - |
97 |
| - original_width, original_height = img.size |
98 |
| - |
99 |
| - new_width, new_height = calculate_scaled_size( |
100 |
| - original_width, original_height, *size |
101 |
| - ) |
102 |
| - |
103 |
| - if new_width >= original_width or new_height >= original_height: |
104 |
| - # If the requested size is larger than the original image, |
105 |
| - # return the original image |
106 |
| - if raise_on_noop: |
107 |
| - raise ThumbnailProcessNoop() |
108 |
| - return image_bytes |
109 |
| - |
110 |
| - logging.debug( |
111 |
| - f"Resizing image from {img.size} to {(new_width, new_height)}" |
112 |
| - ) |
113 |
| - img = img.resize((new_width, new_height), Image.LANCZOS) # type: ignore |
114 |
| - img_byte_arr = io.BytesIO() |
115 |
| - |
116 |
| - # Adjustments for specific formats |
117 |
| - if target_format == "JPEG": |
118 |
| - if img.mode != "RGB": |
119 |
| - img = img.convert("RGB") |
120 |
| - img.save(img_byte_arr, format=target_format, optimize=True, quality=85) |
121 |
| - else: |
122 |
| - img.save(img_byte_arr, format=target_format) |
123 |
| - |
124 |
| - return img_byte_arr.getvalue() |
| 90 | + try: |
| 91 | + with Image.open(io.BytesIO(image_bytes)) as img: |
| 92 | + target_format = format or img.format or "JPEG" |
| 93 | + |
| 94 | + # Ensure that we have valid dimensions |
| 95 | + if size == (None, None): |
| 96 | + raise ValueError("Both width and height cannot be None") |
| 97 | + |
| 98 | + original_width, original_height = img.size |
| 99 | + |
| 100 | + new_width, new_height = calculate_scaled_size( |
| 101 | + original_width, original_height, *size |
| 102 | + ) |
| 103 | + |
| 104 | + if new_width >= original_width or new_height >= original_height: |
| 105 | + # If the requested size is larger than the original image, |
| 106 | + # return the original image |
| 107 | + if raise_on_noop: |
| 108 | + raise ThumbnailProcessNoop() |
| 109 | + return image_bytes |
| 110 | + |
| 111 | + logging.debug( |
| 112 | + f"Resizing image from {img.size} to {(new_width, new_height)}" |
| 113 | + ) |
| 114 | + img = img.resize((new_width, new_height), Image.LANCZOS) # type: ignore |
| 115 | + img_byte_arr = io.BytesIO() |
| 116 | + |
| 117 | + # Adjustments for specific formats |
| 118 | + if target_format == "JPEG": |
| 119 | + if img.mode != "RGB": |
| 120 | + img = img.convert("RGB") |
| 121 | + img.save( |
| 122 | + img_byte_arr, format=target_format, optimize=True, quality=85 |
| 123 | + ) |
| 124 | + else: |
| 125 | + img.save(img_byte_arr, format=target_format) |
| 126 | + |
| 127 | + return img_byte_arr.getvalue() |
| 128 | + except UnidentifiedImageError: |
| 129 | + raise ValueError("Invalid image format") |
125 | 130 |
|
126 | 131 | # Run the blocking image processing in a separate thread
|
127 | 132 | normalized_bytes = await run_in_threadpool(process_image)
|
|
0 commit comments