Add support to draw images via MCP on the RLCD display

This commit is contained in:
Adolfo Reyna
2026-06-01 12:41:14 -04:00
parent 17017ff6e1
commit 0c67ff4e20
2 changed files with 111 additions and 0 deletions
+68
View File
@@ -24,6 +24,74 @@ def main():
# Parse request to ensure it's valid JSON
req_data = json.loads(line.strip())
# Intercept draw_image tool and pre-process the image on the host PC
if req_data.get("method") == "tools/call" and req_data.get("params", {}).get("name") == "draw_image":
try:
args = req_data.get("params", {}).get("arguments", {})
image_base64 = args.get("image_base64")
if not image_base64:
raise ValueError("Missing image_base64 parameter")
# Strip data URI prefix if present
if image_base64.startswith("data:"):
if ";base64," in image_base64:
image_base64 = image_base64.split(";base64,")[1]
import base64
import io
from PIL import Image
img_bytes = base64.b64decode(image_base64)
img = Image.open(io.BytesIO(img_bytes))
# Convert to grayscale
img = img.convert("L")
# Resize to fit screen dimensions (400x300 max)
max_w = int(args.get("maxWidth", 400))
max_h = int(args.get("maxHeight", 300))
# Prevent going over physical screen bounds
max_w = min(max_w, 400)
max_h = min(max_h, 300)
img.thumbnail((max_w, max_h))
# Convert to 1-bit monochrome (with optional Floyd-Steinberg dithering)
dither = args.get("dither", True)
img_1bit = img.convert("1", dither=Image.FLOYDSTEINBERG if dither else Image.NONE)
# Save as binary PBM (P4 format) using PPM format writer on mode 1
pbm_io = io.BytesIO()
img_1bit.save(pbm_io, format="PPM")
pbm_data = pbm_io.getvalue()
# Encode processed PBM to base64
pbm_b64 = base64.b64encode(pbm_data).decode("utf-8")
# Substitute arguments for ESP32
new_args = {
"pbm_base64": pbm_b64,
"x": args.get("x", 0),
"y": args.get("y", 0)
}
req_data["params"]["arguments"] = new_args
except Exception as e:
# Return error response directly to client without contacting ESP32
err_resp = {
"jsonrpc": "2.0",
"error": {
"code": -32602,
"message": f"Bridge image preprocessing failed: {str(e)}"
},
"id": req_data.get("id")
}
sys.stdout.write(json.dumps(err_resp) + "\n")
sys.stdout.flush()
continue
# Forward the JSON-RPC request to the ESP32 board via HTTP POST
req = urllib.request.Request(
url,