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()