mupdf (Rust)
| Language | Rust |
|---|---|
| License | AGPL-3.0 (MuPDF is AGPL-3.0 or commercial from Artifex) |
| Repository | github.com/messense/mupdf-rs |
| Documentation | docs.rs/mupdf |
| Depends on | MuPDF, built from source by mupdf-sys (needs a C compiler and clang for bindgen) |
| Read / write | yes / no (XPS and OpenXPS; converts to PDF) |
The mupdf crate wraps MuPDF’s C API in safe Rust types. Document::open handles XPS and OpenXPS (the xps feature is on by default), and pages work the same as for PDF: to_pixmap, text, to_svg, bounds. Document::convert_to_pdf copies pages into a new PdfDocument that you can save.
The first build compiles MuPDF and takes a few minutes. The crate is AGPL-3.0 like MuPDF; closed-source use needs a commercial MuPDF license.
Installation#
TOML
[dependencies]
mupdf = "0.8"
Basic usage: render each XPS page to PNG#
Rust
use mupdf::{Colorspace, Document, ImageFormat, Matrix};
fn main() -> Result<(), mupdf::Error> {
let doc = Document::open("in.xps")?; // .xps or .oxps
let n = doc.page_count()?;
println!("{} pages", n);
let scale = 150.0 / 72.0; // 150 dpi; MuPDF works in points
for i in 0..n {
let page = doc.load_page(i)?;
let pixmap = page.to_pixmap(
&Matrix::new_scale(scale, scale),
&Colorspace::device_rgb(),
false, // no alpha
true, // show annotations and widgets
)?;
pixmap.save_as(&format!("page-{:03}.png", i + 1), ImageFormat::PNG)?;
}
Ok(())
}
How to extract text from an XPS file#
Rust
use mupdf::{Document, TextExtractOptions};
fn main() -> Result<(), mupdf::Error> {
let doc = Document::open("in.xps")?;
for i in 0..doc.page_count()? {
let page = doc.load_page(i)?;
println!("{}", page.text(TextExtractOptions::default())?);
}
Ok(())
}
How to convert XPS to PDF#
Rust
use mupdf::Document;
fn main() -> Result<(), mupdf::Error> {
let doc = Document::open("in.oxps")?;
let pdf = doc.convert_to_pdf(0, -1, 0)?; // first page, last page (-1 = end), rotation
pdf.save("out.pdf")?;
Ok(())
}
How to check the format and page sizes#
Rust
use mupdf::{Document, MetadataName};
let doc = Document::open("in.xps")?;
println!("format: {}", doc.metadata(MetadataName::Format)?); // "XPS"
for i in 0..doc.page_count()? {
let r = doc.load_page(i)?.bounds()?;
println!("page {}: {} x {} pt", i + 1, r.x1 - r.x0, r.y1 - r.y0);
}
Tips#
- Open XPS data from memory with
Document::from_bytes(&data, "xps"). page.to_svg(&Matrix::IDENTITY)turns a page into SVG markup.- To keep builds smaller, disable default features and enable only what you need (
default-features = false, features = ["xps"]).