From 356e476d1dd0d2d9eb866df7c6f82a21018351c8 Mon Sep 17 00:00:00 2001 From: hermes-agent Date: Wed, 9 Sep 2026 14:58:14 +0000 Subject: [PATCH] get_page_image: add bbox crop parameter (normalized [x0,y0,x1,y1]) Render only a cropped region of a PDF page via PyMuPDF clip rect. Coordinates are normalized 0-1 relative to the page, matching the bbox returned by zotero_get_page_layout. Keeps rendered figure images small so they can be embedded inline as base64 data URIs. --- src/pdf_mcp/server.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/pdf_mcp/server.py b/src/pdf_mcp/server.py index b5ff010..5fd84c6 100644 --- a/src/pdf_mcp/server.py +++ b/src/pdf_mcp/server.py @@ -207,8 +207,9 @@ def get_page_image( page: int = 1, dpi: int = 150, output: Literal["base64", "file"] = "base64", + bbox: list[float] | None = None, ): - """Render a single PDF page as a PNG image. + """Render a single PDF page (or a cropped region) as a PNG image. Args: filename: Path to a PDF file. @@ -216,10 +217,27 @@ def get_page_image( dpi: Image resolution. Default 150 (good balance of readability and size). output: "base64" returns the image inline as MCP image content. "file" writes to a temp file and returns the path. + bbox: Optional crop region as [x0, y0, x1, y1] in normalized + coordinates (0-1 relative to the page). Renders only that + region, which keeps the image small — ideal for a figure or + table. Use zotero_get_page_layout on the Zotero backend to + get the bbox of a figure. If omitted, renders the full page. """ doc = fitz.open(filename) pdf_page = doc[page - 1] - pixmap = pdf_page.get_pixmap(dpi=dpi) + if bbox: + x0, y0, x1, y1 = bbox + # Normalized (0-1) coords -> points + pr = pdf_page.rect + clip = fitz.Rect( + pr.x0 + x0 * pr.width, + pr.y0 + y0 * pr.height, + pr.x0 + x1 * pr.width, + pr.y0 + y1 * pr.height, + ) + pixmap = pdf_page.get_pixmap(dpi=dpi, clip=clip) + else: + pixmap = pdf_page.get_pixmap(dpi=dpi) png_bytes = pixmap.tobytes("png") doc.close()