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 = '''
'''
@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)