pdfium-render 0.5.2

A high-level idiomatic Rust wrapper around Pdfium, the C++ PDF library used by the Google Chromium project.
Documentation

Idiomatic Rust bindings for Pdfium

pdfium-render provides an idiomatic high-level Rust interface around the low-level bindings to Pdfium exposed by the excellent pdfium-sys crate.

    // Exports each page in the given test PDF file as a separate JPEG image.

    use pdfium_render::{pdfium::Pdfium, bitmap::PdfBitmapRotation, bitmap_config::PdfBitmapConfig};
    use image::ImageFormat;

    let password = None;
    
    let document = Pdfium::new(Pdfium::bind_to_system_library().unwrap())
        .load_pdf_from_file("test.pdf", password).unwrap();
    
    let bitmap_render_config = PdfBitmapConfig::new()
        .set_target_width(2000)
        .set_maximum_height(2000)
        .rotate_if_landscape(PdfBitmapRotation::Degrees90, true);
 
    document.pages().iter().for_each(|page| {
        page.get_bitmap_with_config(&bitmap_render_config).unwrap()
            .as_image() // Renders this page to an Image::DynamicImage
            .as_bgra8().unwrap()
            .save_with_format(format!("test-page-{}.jpg", page.index()), ImageFormat::Jpeg).unwrap();
    });

In addition to providing a more natural interface to Pdfium, pdfium-render differs from pdfium-sys in several other important ways:

  • pdfium-render uses libloading to late bind to a Pdfium library at run-time, whereas pdfium-sys binds to a library at compile-time. By binding to Pdfium at run-time instead of compile-time, pdfium-render can dynamically switch between bundled libraries and system libraries and provide idiomatic Rust error handling in situations where a Pdfium library is not available.
  • Late binding to Pdfium means that pdfium-render can be compiled to WASM for running in a browser; this is not possible with pdfium-sys.
  • Pdfium is composed as a set of separate modules, each covering a separate aspects of PDF creation, rendering, and editing. pdfium-sys only provides bindings for the subset of functions exposed by Pdfium's view module; pdfium-render aims to ultimately provide bindings to all non-interactive functions exposed by all Pdfium modules, including document creation and editing functions. This is a work in progress.
  • Pages rendered by Pdfium can be exported as instances of Image::DynamicImage for easy, idiomatic post-processing.

What's new

Version 0.5.2 adds bindings to Pdfium's FPDF_GetPageBoundingBox(), FPDFDoc_GetPageMode(), FPDFPage_Get*Box(), and FPDFPage_Set*Box() functions and exposes the PdfPageBoundaries collection, accessed from the PdfPage::boundaries() function.

Porting existing Pdfium code from other languages

The high-level idiomatic Rust interface provided by the Pdfium struct is entirely optional; the Pdfium struct wraps around raw FFI bindings defined in the PdfiumLibraryBindings trait, and it is completely feasible to simply use those raw FFI bindings directly rather than the high level interface. This makes porting existing code that calls FPDF_* functions very straight-forward, while still gaining the benefits of late binding and WASM compatibility. For instance, the following code snippet (taken from a C++ sample):

    string test_doc = "test.pdf";

    FPDF_InitLibrary();
    FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
    // ... do something with doc
    FPDF_CloseDocument(doc);
    FPDF_DestroyLibrary();

would translate to the following Rust code:

    let bindings = Pdfium::bind_to_system_library().unwrap();
    
    let test_doc = "test.pdf";

    bindings.FPDF_InitLibrary();
    let doc = bindings.FPDF_LoadDocument(test_doc, None);
    // ... do something with doc
    bindings.FPDF_CloseDocument(doc);
    bindings.FPDF_DestroyLibrary();

External Pdfium builds

pdfium-render does not bundle Pdfium at all. You can either bind to a system-provided library or package an external build of Pdfium alongside your Rust application. When compiling to WASM, packaging an external build of Pdfium as a separate WASM module is essential.

Compiling to WASM

See https://github.com/ajrcarey/pdfium-render/tree/master/examples for a full example that shows how to bundle a Rust application using pdfium-render alongside a pre-built Pdfium WASM module for inspection and rendering of PDF files in a web browser.

Development status

The initial focus of this crate has been on rendering pages in a PDF file; consequently, FPDF_* functions related to bitmaps and rendering have been prioritised. By 1.0, the functionality of all FPDF_* functions exported by all Pdfium modules will be available, with the exception of certain functions specific to interactive scripting, user interaction, and printing.

If you need a function that is not currently exposed, just raise an issue.

Version history

  • 0.5.2: adds bindings for FPDF_GetPageBoundingBox(), FPDFDoc_GetPageMode(), FPDFPage_Get*Box(), and FPDFPage_Set*Box() functions, exposes PdfPageBoundaries collection
  • 0.5.1: adds bindings for FPDFPage_GetRotation() and FPDFPage_SetRotation() functions, exposes PdfMetadata collection
  • 0.5.0: adds rendering of annotations and form field elements, thanks to an excellent contribution from https://github.com/inzanez
  • 0.4.2: bug fixes in PdfBitmapConfig implementation
  • 0.4.1: improvements to documentation and READMEs
  • 0.4.0: initial release