CoolFace
Apppublic

henavis/stippleart

sourceHugging Facemitupdated 11mo agoView on Hugging Face
0likes
api.py131 linesDownload Raw Back to root
1from fastapi import FastAPI, UploadFile, File, Form2from fastapi.responses import StreamingResponse, HTMLResponse, JSONResponse3from fastapi.staticfiles import StaticFiles4import io, cv2, numpy as np5 6from stipple_core import (7    run_stipple, export_svg_bytes, export_csv_bytes, export_gcode_bytes8)9 10app = FastAPI(title="Stipple Art Web (Exact Vector Preview)")11app.mount("/static", StaticFiles(directory="static"), name="static")12 13@app.get("/", response_class=HTMLResponse)14def home():15    return open("static/index.html", "r", encoding="utf-8").read()16 17def _read_bgr(upload: UploadFile):18    data = np.frombuffer(upload.file.read(), np.uint8)19    bgr = cv2.imdecode(data, cv2.IMREAD_COLOR)20    if bgr is None:21        raise ValueError("Bad image file")22    return bgr23 24@app.post("/process")25def process(26    image: UploadFile = File(...),27    dpi: int = Form(5),28    cell_size_mm: int = Form(3),29    max_dots: int = Form(60),30    sensitivity: float = Form(2.0),31    min_dia_mm: float = Form(0.2),32    max_dia_mm: float = Form(1.5),33    brightness: int = Form(0),34    contrast: float = Form(1.0),35    gamma_val: float = Form(1.0),36    blur_sigma: float = Form(0.0),37    sharpen_amt: float = Form(0.0),38    sharpen_sigma: float = Form(1.0),39    clahe_clip: float = Form(0.0),40    clahe_tile: int = Form(8),41    flip_y: bool = Form(False),42    fix_seed: bool = Form(True),43):44    bgr = _read_bgr(image)45    png_bytes, _ = run_stipple(46        bgr, dpi, cell_size_mm, max_dots, sensitivity,47        min_dia_mm, max_dia_mm, brightness, contrast, gamma_val,48        blur_sigma, sharpen_amt, sharpen_sigma, clahe_clip, clahe_tile,49        flip_y, fix_seed, preview_fast=False50    )51    return StreamingResponse(io.BytesIO(png_bytes), media_type="image/png")52 53# ✅ תצוגת ווקטור חדה בזמן אמת54@app.post("/preview/vector")55def preview_vector(56    image: UploadFile = File(...),57    dpi: int = Form(5),58    cell_size_mm: int = Form(3),59    max_dots: int = Form(60),60    sensitivity: float = Form(2.0),61    min_dia_mm: float = Form(0.2),62    max_dia_mm: float = Form(1.5),63    brightness: int = Form(0),64    contrast: float = Form(1.0),65    gamma_val: float = Form(1.0),66    blur_sigma: float = Form(0.0),67    sharpen_amt: float = Form(0.0),68    sharpen_sigma: float = Form(1.0),69    clahe_clip: float = Form(0.0),70    clahe_tile: int = Form(8),71    flip_y: bool = Form(False),72    fix_seed: bool = Form(True),73):74    data = np.frombuffer(image.file.read(), np.uint8)75    bgr = cv2.imdecode(data, cv2.IMREAD_COLOR)76    _, points = run_stipple(77        bgr, dpi, cell_size_mm, max_dots, sensitivity,78        min_dia_mm, max_dia_mm, brightness, contrast, gamma_val,79        blur_sigma, sharpen_amt, sharpen_sigma, clahe_clip, clahe_tile,80        flip_y, fix_seed, preview_fast=False81    )82    _, svg_bytes = export_svg_bytes(points)83    return StreamingResponse(io.BytesIO(svg_bytes), media_type="image/svg+xml")84 85@app.post("/export/{fmt}")86def export(87    fmt: str,88    image: UploadFile = File(...),89    dpi: int = Form(5),90    cell_size_mm: int = Form(3),91    max_dots: int = Form(60),92    sensitivity: float = Form(2.0),93    min_dia_mm: float = Form(0.2),94    max_dia_mm: float = Form(1.5),95    brightness: int = Form(0),96    contrast: float = Form(1.0),97    gamma_val: float = Form(1.0),98    blur_sigma: float = Form(0.0),99    sharpen_amt: float = Form(0.0),100    sharpen_sigma: float = Form(1.0),101    clahe_clip: float = Form(0.0),102    clahe_tile: int = Form(8),103    flip_y: bool = Form(False),104    fix_seed: bool = Form(True),105    servo_up: int = Form(30),106    servo_down: int = Form(90),107    dwell_up: int = Form(80),108    dwell_down: int = Form(120),109    feedrate: int = Form(3000),110):111    bgr = _read_bgr(image)112    _, points = run_stipple(113        bgr, dpi, cell_size_mm, max_dots, sensitivity,114        min_dia_mm, max_dia_mm, brightness, contrast, gamma_val,115        blur_sigma, sharpen_amt, sharpen_sigma, clahe_clip, clahe_tile,116        flip_y, fix_seed, preview_fast=False117    )118    if fmt == "svg":119        fname, data = export_svg_bytes(points)120        mt = "image/svg+xml"121    elif fmt == "csv":122        fname, data = export_csv_bytes(points)123        mt = "text/csv"124    elif fmt == "gcode":125        fname, data = export_gcode_bytes(points, servo_up, servo_down, dwell_up, dwell_down, feedrate)126        mt = "text/plain"127    else:128        return JSONResponse({"error": "format not supported"}, status_code=400)129    headers = {"Content-Disposition": f'attachment; filename="{fname}"'}130    return StreamingResponse(io.BytesIO(data), media_type=mt, headers=headers)131