from fastapi import FastAPI, UploadFile, File, Form from fastapi.responses import HTMLResponse, FileResponse from PIL import Image import io, math, json, os app = FastAPI() BASE = os.getcwd() OUTPUT_DIR = os.path.join(BASE, 'output') os.makedirs(OUTPUT_DIR, exist_ok=True) HTML = '''

Sprite Tool Suite

Total Tiles: 0

操作:直接拖拽平移。Cmd+點擊選取兩點定一區。

''' @app.get('/', response_class=HTMLResponse) def home(): return HTML @app.post('/export') async def export(file: UploadFile = File(...), cols: int = Form(...), rows: int = Form(...), outCols: int = Form(...), outRows: int = Form(...), name: str = Form('output.png'), regions: str = Form(...)): data = await file.read() img = Image.open(io.BytesIO(data)).convert('RGBA') cw, ch = img.width // cols, img.height // rows reg_list = json.loads(regions) tiles = [] for r in reg_list: for y in range(r['y1'], r['y2'] + 1): for x in range(r['x1'], r['x2'] + 1): tiles.append((x, y)) if not tiles: return HTMLResponse('No tiles selected', status_code=400) needed_rows = math.ceil(len(tiles) / outCols) out = Image.new('RGBA', (outCols * cw, needed_rows * ch), (0, 0, 0, 0)) for i, (tx, ty) in enumerate(tiles): tile = img.crop((tx * cw, ty * ch, (tx + 1) * cw, (ty + 1) * ch)) out.paste(tile, ((i % outCols) * cw, (i // outCols) * ch)) path = os.path.join(OUTPUT_DIR, name) out.save(path) return FileResponse(path, filename=name, media_type='image/png') if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)