| from io import BytesIO |
|
|
| from PIL import Image, ImageOps, UnidentifiedImageError |
| from fastapi import HTTPException, UploadFile |
|
|
|
|
| def compress_image(file: UploadFile) -> bytes: |
| if not file.content_type or not file.content_type.startswith("image/"): |
| raise HTTPException(status_code=400, detail="File must be an image") |
| try: |
| file.file.seek(0) |
| original_bytes = file.file.read() |
| image = Image.open(BytesIO(original_bytes)) |
| image = ImageOps.exif_transpose(image) |
| max_size = 512 |
| image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS) |
| if image.mode not in ("RGB", "RGBA"): |
| image = image.convert("RGBA") |
| buffer = BytesIO() |
| image.save(buffer, format="PNG", optimize=True, compress_level=9) |
| return buffer.getvalue() |
| except (UnidentifiedImageError, OSError): |
| raise HTTPException(status_code=400, detail="Invalid image file") |
| finally: |
| try: |
| file.file.close() |
| except Exception: |
| pass |
|
|