import io
import base64
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import HTMLResponse, Response
from PIL import Image
app = FastAPI()
HTML = """
Sprite Merger
"""
@app.get("/", response_class=HTMLResponse)
async def index():
return HTML
@app.post("/merge")
async def merge_sprites(
main_image: UploadFile = File(...),
source_image: UploadFile = File(...),
main_cols: int = Form(...),
main_rows: int = Form(...),
target_col: int = Form(...),
target_row: int = Form(...),
output_name: str = Form("output.png"),
):
main_data = await main_image.read()
source_data = await source_image.read()
main_img = Image.open(io.BytesIO(main_data)).convert("RGBA")
source_img = Image.open(io.BytesIO(source_data)).convert("RGBA")
main_w, main_h = main_img.size
tile_w = main_w // main_cols
tile_h = main_h // main_rows
# 將來源圖縮放至 tile 尺寸
source_resized = source_img.resize((tile_w, tile_h), Image.NEAREST)
paste_x = target_col * tile_w
paste_y = target_row * tile_h
result = main_img.copy()
result.paste(source_resized, (paste_x, paste_y), source_resized)
buf = io.BytesIO()
result.save(buf, format="PNG")
buf.seek(0)
return Response(
content=buf.read(),
media_type="image/png",
headers={"Content-Disposition": f'attachment; filename="{output_name}"'},
)