from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import StreamingResponse from PIL import Image import io app = FastAPI(title="Advanced Image Converter") ALLOWED_OUTPUT_FORMATS = ["jpeg", "png", "gif", "bmp", "tiff", "webp"] @app.post("/convert_image/") async def convert_image( file: UploadFile = File(...), output_format: str = "jpeg", quality: int = 95 # For JPEG/WebP, adjust compression quality (0-100) ): """ Converts an uploaded image to the specified format. - Supports common image formats as input. - Output formats: JPEG, PNG, GIF, BMP, TIFF, WebP. - For JPEG and WebP, you can adjust the `quality` (0-100). """ if output_format.lower() not in ALLOWED_OUTPUT_FORMATS: raise HTTPException( status_code=400, detail=f"Invalid output format. Allowed formats: {', '.join(ALLOWED_OUTPUT_FORMATS)}", ) if output_format.lower() in ["jpeg", "webp"] and not (0 <= quality <= 100): raise HTTPException( status_code=400, detail="Quality must be between 0 and 100 for JPEG and WebP." ) try: image = Image.open(io.BytesIO(await file.read())) except Exception as e: raise HTTPException(status_code=400, detail="Invalid image file.") from e output_io = io.BytesIO() try: save_kwargs = {} if output_format.lower() in ["jpeg", "webp"]: save_kwargs["quality"] = quality image.save(output_io, format=output_format.upper(), **save_kwargs) except KeyError: raise HTTPException( status_code=400, detail=f"Conversion to {output_format} failed." ) except Exception as e: raise HTTPException(status_code=500, detail=f"Image processing error: {e}") output_io.seek(0) media_type = f"image/{output_format.lower()}" if output_format.lower() == "tiff": media_type = "image/tiff" # Special case for TIFF return StreamingResponse(output_io, media_type=media_type)