feat(api): support asImage=true on screen and zoom
All checks were successful
python-syntax / syntax-check (push) Successful in 4s

This commit is contained in:
2026-04-05 20:03:32 +02:00
parent 4aa51e2d69
commit 683f2d5961
3 changed files with 28 additions and 8 deletions

View File

@@ -5,7 +5,7 @@ import time
import uuid
from typing import Literal, Optional
from fastapi import Depends, FastAPI, Header, HTTPException
from fastapi import Depends, FastAPI, Header, HTTPException, Response
from pydantic import BaseModel, Field, model_validator
@@ -160,13 +160,17 @@ def _capture_screen():
return image, {"x": mon["left"], "y": mon["top"], "width": mon["width"], "height": mon["height"]}
def _encode_image(image, image_format: str, jpeg_quality: int) -> str:
def _serialize_image(image, image_format: str, jpeg_quality: int) -> bytes:
buf = io.BytesIO()
if image_format == "jpeg":
image.save(buf, format="JPEG", quality=jpeg_quality)
else:
image.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode("ascii")
return buf.getvalue()
def _encode_image(image, image_format: str, jpeg_quality: int) -> str:
return base64.b64encode(_serialize_image(image, image_format, jpeg_quality)).decode("ascii")
def _draw_grid(image, region_x: int, region_y: int, rows: int, cols: int, include_labels: bool):
@@ -335,6 +339,7 @@ def screen(
include_labels: bool = True,
image_format: Literal["png", "jpeg"] = "png",
jpeg_quality: int = 85,
asImage: bool = False,
_: None = Depends(_auth),
):
req = ScreenRequest(
@@ -354,6 +359,11 @@ def screen(
out_img, grid_meta = _draw_grid(base_img, mon["x"], mon["y"], req.grid_rows, req.grid_cols, req.include_labels)
meta.update(grid_meta)
if asImage:
image_bytes = _serialize_image(out_img, req.image_format, req.jpeg_quality)
media_type = "image/jpeg" if req.image_format == "jpeg" else "image/png"
return Response(content=image_bytes, media_type=media_type)
encoded = _encode_image(out_img, req.image_format, req.jpeg_quality)
return {
"ok": True,
@@ -370,7 +380,7 @@ def screen(
@app.post("/zoom")
def zoom(req: ZoomRequest, _: None = Depends(_auth)):
def zoom(req: ZoomRequest, asImage: bool = False, _: None = Depends(_auth)):
base_img, mon = _capture_screen()
cx = req.center_x - mon["x"]
@@ -404,6 +414,11 @@ def zoom(req: ZoomRequest, _: None = Depends(_auth)):
out_img, grid_meta = _draw_grid(crop, region_x, region_y, req.grid_rows, req.grid_cols, req.include_labels)
meta.update(grid_meta)
if asImage:
image_bytes = _serialize_image(out_img, req.image_format, req.jpeg_quality)
media_type = "image/jpeg" if req.image_format == "jpeg" else "image/png"
return Response(content=image_bytes, media_type=media_type)
encoded = _encode_image(out_img, req.image_format, req.jpeg_quality)
return {