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