|
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 |
|
): |
|
""" |
|
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" |
|
|
|
return StreamingResponse(output_io, media_type=media_type) |