# How to Generate Screenshots from Documents for LLM Agents Using LiteParse

> Easily generate high-fidelity screenshots from documents for LLM agents with LiteParse. Convert PDFs to PNG or JPEG using a unified API across Rust Nodejs and Python.

- Repository: [LlamaIndex/liteparse](https://github.com/run-llama/liteparse)
- Tags: how-to-guide
- Published: 2026-06-07

---

**LiteParse's render module converts PDF pages into high-fidelity PNG or JPEG images via the PDFium engine, exposing a unified API across Rust, Node.js, and Python for direct ingestion by multimodal LLMs.**

The `run-llama/liteparse` repository provides a document parsing toolkit specifically designed for LLM workflows, including a dedicated **render module** that transforms PDF pages into raster images. By leveraging Google's PDFium engine for high-fidelity rasterization, LiteParse enables agents to process visual document content through a consistent interface available in multiple programming languages.

## How the LiteParse Render Module Works

The rendering functionality resides in [`crates/liteparse/src/render.rs`](https://github.com/run-llama/liteparse/blob/main/crates/liteparse/src/render.rs), which implements a hardware-accelerated pipeline for converting vector PDF content into bitmap images. This module interfaces directly with the **PDFium** library to handle complex rendering operations including rotation, scaling, and color space conversion.

### Core Rendering Pipeline

The process begins in [`crates/liteparse/src/parser.rs`](https://github.com/run-llama/liteparse/blob/main/crates/liteparse/src/parser.rs) where `LiteParse::new()` initializes the PDFium context, then proceeds through four distinct stages:

1. **Initialize the Parser** – Call `LiteParse::new()` to load the PDF into memory via PDFium.
2. **Acquire Page Handle** – Access individual pages through the parser's indexing method, which returns a `Page` struct representing the specific document page.
3. **Configure RenderOptions** – Instantiate `RenderOptions` to specify output format (`ImageFormat::Png` or `ImageFormat::Jpeg`), target **DPI** (typically 150-300 for LLM consumption), and optional cropping regions.
4. **Execute render_page()** – The `render_page()` function in [`render.rs`](https://github.com/run-llama/liteparse/blob/main/render.rs) processes the bitmap through the `image` crate encoder and returns `Result<Vec<u8>>` containing the encoded image bytes.

### Cross-Platform Binding Architecture

LiteParse exposes identical rendering capabilities across ecosystems without duplicating native code. The **Node.js** wrapper in [`packages/node/src/lib.ts`](https://github.com/run-llama/liteparse/blob/main/packages/node/src/lib.ts) marshals calls to the Rust binary through a native interface, returning `Uint8Array` objects. Similarly, the **Python** implementation in [`packages/python/liteparse/parser.py`](https://github.com/run-llama/liteparse/blob/main/packages/python/liteparse/parser.py) wraps the Rust core and returns standard Python `bytes` objects suitable for immediate file writing or base64 encoding. The same logic compiles to **WebAssembly** for browser-side execution.

## Rendering Documents to Images in Rust

The Rust implementation provides the native interface that powers all language bindings. Access the render functionality directly through the `liteparse::render` module:

```rust
use liteparse::parser::LiteParse;
use liteparse::render::{render_page, RenderOptions};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize parser with PDFium backend
    let parser = LiteParse::new("sample.pdf").await?;
    
    // Retrieve first page (0-indexed)
    let page = parser.page(0)?;
    
    // Configure 300 DPI PNG output
    let opts = RenderOptions {
        dpi: 300,
        format: liteparse::render::ImageFormat::Png,
        ..Default::default()
    };
    
    // Generate screenshot bytes
    let png_bytes = render_page(&page, &opts)?;
    
    // Persist or transmit to LLM agent
    std::fs::write("page0.png", png_bytes)?;
    Ok(())
}

```

This pattern executes entirely within the Rust runtime, utilizing the `image` crate for efficient bitmap encoding before returning the byte vector.

## Generating Screenshots in Node.js and Python

The library maintains API parity across language bindings, allowing identical workflows in JavaScript and Python environments.

### Node.js Implementation

The TypeScript wrapper in [`packages/node/src/lib.ts`](https://github.com/run-llama/liteparse/blob/main/packages/node/src/lib.ts) exposes `renderPage()` as an async method that returns a `Uint8Array`:

```javascript
import { LiteParse } from "liteparse";

async function screenshot() {
  // Load document into PDFium
  const parser = await LiteParse.open("sample.pdf");
  
  // Render page 0 at 300 DPI as PNG
  const imgBuffer = await parser.renderPage(0, { dpi: 300, format: "png" });
  
  // Convert to Buffer for file system or base64 encoding
  const fs = require("fs");
  fs.writeFileSync("page0.png", Buffer.from(imgBuffer));
}
screenshot();

```

### Python Implementation

The Python package wraps the native Rust functions in [`packages/python/liteparse/parser.py`](https://github.com/run-llama/liteparse/blob/main/packages/python/liteparse/parser.py), exposing `render_page()` with named parameters:

```python
from liteparse import LiteParse

def generate_screenshot():
    # Initialize with PDFium backend

    parser = LiteParse("sample.pdf")
    
    # Render first page at 300 DPI

    png_bytes = parser.render_page(0, dpi=300, format="png")
    
    # Write to filesystem or encode for LLM prompt

    with open("page0.png", "wb") as f:
        f.write(png_bytes)

generate_screenshot()

```

## Optimizing Image Output for LLM Agents

When preparing screenshots for multimodal LLM consumption, configure `RenderOptions` to balance clarity and token efficiency. Set **DPI** between 150 and 300 to ensure text legibility while managing file size. Use **PNG** format for documents with sharp text and line art to avoid JPEG compression artifacts, or select **JPEG** with quality settings for photographic content.

The `render_page()` function returns raw bytes suitable for base64 encoding when passed directly to LLM APIs. Since the output is `Vec<u8>` in Rust (or equivalent `bytes`/`Uint8Array` in other languages), you can stream the image data over HTTP or embed it immediately in JSON payloads without intermediate file I/O.

## Summary

- **LiteParse** provides native PDF rendering in [`crates/liteparse/src/render.rs`](https://github.com/run-llama/liteparse/blob/main/crates/liteparse/src/render.rs) using the PDFium engine for high-fidelity rasterization.
- The **`render_page()`** function accepts configurable `RenderOptions` including DPI, format (PNG/JPEG), and cropping parameters.
- Language bindings in [`packages/node/src/lib.ts`](https://github.com/run-llama/liteparse/blob/main/packages/node/src/lib.ts) and [`packages/python/liteparse/parser.py`](https://github.com/run-llama/liteparse/blob/main/packages/python/liteparse/parser.py) expose identical functionality to JavaScript and Python without additional native dependencies.
- Output bytes can be written to disk, base64-encoded for LLM prompts, or streamed directly to agents supporting multimodal inputs.

## Frequently Asked Questions

### What image formats does LiteParse support for document screenshots?

LiteParse supports **PNG** and **JPEG** output formats as defined in the `ImageFormat` enum within [`crates/liteparse/src/render.rs`](https://github.com/run-llama/liteparse/blob/main/crates/liteparse/src/render.rs). PNG is recommended for text-heavy documents to preserve sharp edges, while JPEG offers smaller file sizes for image-heavy content at the cost of potential compression artifacts.

### Which DPI setting produces the best results for LLM text recognition?

A **DPI of 300** provides optimal text clarity for most LLM vision systems, balancing detail against file size and processing cost. LiteParse's `RenderOptions` accepts any positive integer value for DPI, allowing you to scale down to 150 DPI for faster processing or up to 600 DPI for documents with fine print.

### How does LiteParse compare to browser-based PDF rendering for LLM agents?

Unlike browser-based solutions that require headless Chromium or external dependencies, LiteParse uses the native **PDFium** library integrated directly into the Rust binary. This eliminates external process calls and reduces memory overhead, while the **WebAssembly** target allows the same rendering code to execute in browser environments without server round-trips.

### Can I render specific regions of a page rather than the full screenshot?

Yes. The `RenderOptions` struct accepts optional cropping parameters that define a sub-region of the PDF page in pixel coordinates. This feature, implemented in [`crates/liteparse/src/render.rs`](https://github.com/run-llama/liteparse/blob/main/crates/liteparse/src/render.rs), allows you to extract specific tables, figures, or text blocks for targeted LLM analysis without processing entire pages.