diff --git a/_grassland.png b/_grassland.png new file mode 100644 index 0000000..216bfa6 Binary files /dev/null and b/_grassland.png differ diff --git a/fireant.png b/fireant.png new file mode 100644 index 0000000..5645a7c Binary files /dev/null and b/fireant.png differ diff --git a/grassland.png b/grassland.png new file mode 100644 index 0000000..8b96763 Binary files /dev/null and b/grassland.png differ diff --git a/sprite_merger.py b/sprite_merger.py new file mode 100644 index 0000000..629ce24 --- /dev/null +++ b/sprite_merger.py @@ -0,0 +1,158 @@ +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 + + + +
+

🧩 Sprite Merger

+

將來源圖片 merge 進主圖的指定 tile 座標

+ +
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+ +
+ + + + +
+ + + + +""" + +@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}"'}, + ) diff --git a/tool.py b/tool.py index d2d333e..c3407c1 100644 --- a/tool.py +++ b/tool.py @@ -9,6 +9,7 @@ from sprite_tool_fullstack import app as grid_app from sprite_webtool import app as picker_app from shiny_maker import app as shiny_app from rotate_webtool import app as flipper_app +from sprite_merger import app as merger_app app = FastAPI(title="Game Dev Suite") @@ -21,6 +22,7 @@ NAVBAR_HTML = """ 🎯 Picker Tool ✨ Shiny Maker 🔄 Flipper + 🧩 Merger """ @@ -55,6 +57,7 @@ app.mount("/grid", grid_app) app.mount("/picker", picker_app) app.mount("/shiny", shiny_app) app.mount("/flipper", flipper_app) +app.mount("/merger", merger_app) # 首頁入口 @app.get("/", response_class=HTMLResponse) @@ -76,6 +79,7 @@ async def index(): 🎯 Picker Tool ✨ Shiny Maker 🔄 Flipper + 🧩 Merger