diff --git a/output/output.png b/output/output.png
new file mode 100644
index 0000000..e03bc9e
Binary files /dev/null and b/output/output.png differ
diff --git a/output/output2.png b/output/output2.png
new file mode 100644
index 0000000..da4cbaf
Binary files /dev/null and b/output/output2.png differ
diff --git a/output/sprites_export_1.png b/output/sprites_export_1.png
new file mode 100644
index 0000000..62c00b8
Binary files /dev/null and b/output/sprites_export_1.png differ
diff --git a/output/sprites_export_2.png b/output/sprites_export_2.png
new file mode 100644
index 0000000..a380e9f
Binary files /dev/null and b/output/sprites_export_2.png differ
diff --git a/output/sprites_export_3.png b/output/sprites_export_3.png
new file mode 100644
index 0000000..1024893
Binary files /dev/null and b/output/sprites_export_3.png differ
diff --git a/output/sprites_export_4.png b/output/sprites_export_4.png
new file mode 100644
index 0000000..94440e4
Binary files /dev/null and b/output/sprites_export_4.png differ
diff --git a/output/sprites_export_5.png b/output/sprites_export_5.png
new file mode 100644
index 0000000..fc8ecac
Binary files /dev/null and b/output/sprites_export_5.png differ
diff --git a/output/sprites_export_batch.zip b/output/sprites_export_batch.zip
new file mode 100644
index 0000000..1e22a2d
Binary files /dev/null and b/output/sprites_export_batch.zip differ
diff --git a/rotate_webtool.py b/rotate_webtool.py
new file mode 100644
index 0000000..076d141
--- /dev/null
+++ b/rotate_webtool.py
@@ -0,0 +1,204 @@
+import cv2
+import io
+import numpy as np
+from fastapi import FastAPI, UploadFile, File, Form
+from fastapi.responses import HTMLResponse, StreamingResponse
+
+app = FastAPI()
+
+HTML = '''
+
+
+
+ Sprite Flipper
+
+
+
+
+
+
+
+
🔄 Sprite Flipper
+
將 Sprite Sheet 中每個格子水平翻轉(左右鏡像),並輸出新圖片。
+
+
+
+
+
+
+
+
+
+
+
預覽(原圖)
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+'''
+
+
+def _flip_sprite_sheet(img_bytes: bytes, cols: int, rows: int) -> bytes:
+ """核心翻轉邏輯(來自 rotate.py):將每個 cell 水平翻轉。"""
+ arr = np.frombuffer(img_bytes, dtype=np.uint8)
+ img = cv2.imdecode(arr, cv2.IMREAD_UNCHANGED)
+ if img is None:
+ raise ValueError("無法解碼圖片")
+
+ h, w = img.shape[:2]
+ cell_w = w / cols
+ cell_h = h / rows
+ output = img.copy()
+
+ for r in range(rows):
+ for c in range(cols):
+ x1 = int(c * cell_w)
+ y1 = int(r * cell_h)
+ x2 = int((c + 1) * cell_w)
+ y2 = int((r + 1) * cell_h)
+
+ cell = img[y1:y2, x1:x2]
+ if cell.size == 0:
+ continue
+
+ output[y1:y2, x1:x2] = cv2.flip(cell, 1)
+
+ success, buf = cv2.imencode(".png", output)
+ if not success:
+ raise ValueError("圖片編碼失敗")
+ return buf.tobytes()
+
+
+@app.get("/", response_class=HTMLResponse)
+def home():
+ return HTML
+
+
+@app.post("/flip")
+async def flip(
+ file: UploadFile = File(...),
+ cols: int = Form(10),
+ rows: int = Form(6),
+):
+ data = await file.read()
+ try:
+ result = _flip_sprite_sheet(data, cols, rows)
+ except ValueError as e:
+ from fastapi.responses import PlainTextResponse
+ return PlainTextResponse(str(e), status_code=400)
+
+ return StreamingResponse(
+ io.BytesIO(result),
+ media_type="image/png",
+ headers={"Content-Disposition": 'attachment; filename="flipped.png"'},
+ )
+
+
+if __name__ == "__main__":
+ import uvicorn
+ uvicorn.run(app, host="0.0.0.0", port=8001)
diff --git a/tool.py b/tool.py
index 179f059..d2d333e 100644
--- a/tool.py
+++ b/tool.py
@@ -8,6 +8,7 @@ from starlette.middleware.base import BaseHTTPMiddleware
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
app = FastAPI(title="Game Dev Suite")
@@ -19,6 +20,7 @@ NAVBAR_HTML = """
📏 Grid Tool
🎯 Picker Tool
✨ Shiny Maker
+ 🔄 Flipper
"""
@@ -52,6 +54,7 @@ app.add_middleware(NavbarMiddleware)
app.mount("/grid", grid_app)
app.mount("/picker", picker_app)
app.mount("/shiny", shiny_app)
+app.mount("/flipper", flipper_app)
# 首頁入口
@app.get("/", response_class=HTMLResponse)
@@ -68,10 +71,11 @@ async def index():
Game Developer Tool Suite
請從上方導覽列選擇要使用的工具
-
-
📏 Grid Tool
-
🎯 Picker Tool
-
✨ Shiny Maker
+