Skip to main content

Crate zenpdf

Crate zenpdf 

Source
Expand description

§zenpdf CI crates.io lib.rs docs.rs license

Pure Rust PDF page renderer built on hayro. Renders PDF pages to PixelBuffer<Rgba<u8>> (straight-alpha sRGB RGBA8).

#![forbid(unsafe_code)]

§Quick start

use zenpdf::{render_page, RenderBounds};

let pdf_data = std::fs::read("document.pdf").unwrap();

// Render page 0 at 150 DPI
let page = render_page(&pdf_data, 0, &RenderBounds::Dpi(150.0)).unwrap();
println!("{}x{}", page.buffer.width(), page.buffer.height());

// Fit within 1920px wide
let page = render_page(&pdf_data, 0, &RenderBounds::FitWidth(1920)).unwrap();

§Render bounds

Control output pixel dimensions with RenderBounds:

VariantDescription
Scale(f32)Multiplier on native 72 DPI dimensions. 2.0 = 144 DPI.
Dpi(f32)Render at a specific DPI. 72.0 is native, 300.0 for print.
FitWidth(u32)Scale to fit the given width, preserving aspect ratio.
FitHeight(u32)Scale to fit the given height, preserving aspect ratio.
FitBox { width, height }Scale to fit within a bounding box, preserving aspect ratio.
Exact { width, height }Force exact pixel dimensions (may distort).

§Multi-page rendering

use zenpdf::{render_pages, PdfConfig, PageSelection, RenderBounds};


let config = PdfConfig {
    pages: PageSelection::Range { start: 0, end: 4 },
    bounds: RenderBounds::Dpi(300.0),
    background: [255, 255, 255, 255], // opaque white
    render_annotations: true,
    ..PdfConfig::default()
};

let pages = render_pages(&pdf_data, &config).unwrap();
for page in &pages {
    println!("page {}: {}x{}", page.index, page.buffer.width(), page.buffer.height());
}

§zencodec integration

With the zencodec feature (enabled by default), zenpdf implements zencodec::decode::DecoderConfig for use in codec-agnostic image pipelines.

Default decode renders page 0. Use with_start_frame_index() on the job to select a different page.

use std::borrow::Cow;
use zencodec::decode::{Decode, DecodeJob, DecoderConfig};
use zenpdf::{PdfDecoderConfig, RenderBounds};

let config = PdfDecoderConfig::new()
    .with_bounds(RenderBounds::Dpi(150.0));

let pdf_data = std::fs::read("document.pdf").unwrap();
let output = config.job()
    .decoder(Cow::Borrowed(&pdf_data), &[])
    .unwrap()
    .decode()
    .unwrap();

println!("{}x{}", output.width(), output.height());

Resource limits are enforced when set via with_limits() on the job — input size, output dimensions, and pixel count are all checked before rendering begins.

§Features

FeatureDefaultDescription
zencodecYesImplements zencodec::decode::DecoderConfig for codec-agnostic pipelines

§Dependencies

All dependencies are permissive (MIT, Apache-2.0, Zlib, BSD-3-Clause, Unicode-3.0). No copyleft in the dependency tree.

§Image tech I maintain

State of the art codecs*zenjpeg · zenpng · zenwebp · zengif · zenavif (rav1d-safe · zenrav1e · zenavif-parse · zenavif-serialize) · zenjxl (jxl-encoder · zenjxl-decoder) · zentiff · zenbitmaps · heic · zenraw · zenpdf · ultrahdr · mozjpeg-rs · webpx
Compressionzenflate · zenzop
Processingzenresize · zenfilters · zenquant · zenblend
Metricszensim · fast-ssim2 · butteraugli · resamplescope-rs · codec-eval · codec-corpus
Pixel types & colorzenpixels · zenpixels-convert · linear-srgb · garb
Pipelinezenpipe · zencodec · zencodecs · zenlayout · zennode
ImageResizerImageResizer (C#) — 24M+ NuGet downloads across all packages
ImageflowImage optimization engine (Rust) — .NET · node · go — 9M+ NuGet downloads across all packages
Imageflow ServerThe fast, safe image server (Rust+C#) — 552K+ NuGet downloads, deployed by Fortune 500s and major brands

* as of 2026

§General Rust awesomeness

archmage · magetypes · enough · whereat · zenbench · cargo-copter

And other projects · GitHub @imazen · GitHub @lilith · lib.rs/~lilith · NuGet (over 30 million downloads / 87 packages)

§License

Dual-licensed: AGPL-3.0 or commercial.

I’ve maintained and developed open-source image server software — and the 40+ library ecosystem it depends on — full-time since 2011. Fifteen years of continual maintenance, backwards compatibility, support, and the (very rare) security patch. That kind of stability requires sustainable funding, and dual-licensing is how we make it work without venture capital or rug-pulls. Support sustainable and secure software; swap patch tuesday for patch leap-year.

Our open-source products

Your options:

  • Startup license — $1 if your company has under $1M revenue and fewer than 5 employees. Get a key →
  • Commercial subscription — Governed by the Imazen Site-wide Subscription License v1.1 or later. Apache 2.0-like terms, no source-sharing requirement. Sliding scale by company size. Pricing & 60-day free trial →
  • AGPL v3 — Free and open. Share your source if you distribute.

See LICENSE-COMMERCIAL for details.

§AI-Generated Code Notice

Developed with Claude (Anthropic). Not all code manually reviewed. Review critical paths before production use.

Structs§

PdfConfig
Configuration for PDF page rendering.
PdfDecoderConfig
PDF decoder configuration implementing zencodec::decode::DecoderConfig.
RenderLimits
Resource limits for PDF rendering.
RenderedPage
A rendered PDF page with its pixel data and source dimensions.

Enums§

PageSelection
Which pages to render from a PDF document.
PdfError
Errors from PDF rendering.
RenderBounds
How to size the rendered output for each page.

Statics§

PDF_FORMAT
PDF format definition for zencodec registry.

Functions§

page_count
Returns the number of pages in a PDF document.
page_dimensions
Returns the dimensions (in PDF points) of a specific page.
render_page
Renders a single page from a PDF document.
render_pages
Renders selected pages from a PDF document according to the given configuration.

Type Aliases§

Result