This guide shows developers how to perform common PDF operations involving images. Use the PDFluent SDK to render pages and to add new images.
Image extraction is part of the base crate. No extra features are required.
# Cargo.toml
[dependencies]
pdfluent = "1.0.0"Rasterise any PDF page to a PNG image at a chosen DPI. Works headless with no display server required.
use pdfluent::{PdfDocument, ImageFormat};
fn main() -> pdfluent::Result<()> {
let doc = PdfDocument::open("file.pdf")?;
let png = doc.render_page(1, 150, ImageFormat::Png)?;
std::fs::write("page-1.png", png)?;
Ok(())
}Complete program, compiled against the published crate: Code on GitHub →
The same code, typed and run on screen. Watch on YouTube
Open the document. Rendering is a document-level operation in PDFluent: you choose the output pattern and a page range.
use pdfluent::prelude::*;
let doc = PdfDocument::open("slides.pdf")?;ToImagesOptions::new() defaults to 150 DPI and PNG output. Override DPI and format to taste. For sharp screen previews 150 DPI is fine; print-quality output is 300 DPI.
let opts = ToImagesOptions::new()
.with_dpi(150)
.with_format(ImageFormat::Png);Use .with_pages(from, to) with 1-based inclusive bounds. Omit to render every page.
let opts = ToImagesOptions::new()
.with_dpi(150)
.with_pages(1, 3); // pages 1, 2, 3Pass a filename pattern. The {page} placeholder is substituted with the 1-based page number. If the pattern has no {page}, PDFluent inserts _N before the extension.
let report = doc.to_images("page_{page}.png", opts)?;
for path in &report.paths {
println!("wrote {}", path.display());
}Change the format via .with_format(ImageFormat::Jpeg). JPEG does not carry transparency, so RGBA pixels are flattened to RGB before encoding.
use pdfluent::prelude::*;
let doc = PdfDocument::open("document.pdf")?;
doc.to_images(
"thumb_{page}.jpg",
ToImagesOptions::new()
.with_dpi(72)
.with_format(ImageFormat::Jpeg),
)?;Rasterize individual pages or an entire PDF document to JPEG files at a configurable DPI and quality level.
use pdfluent::{PdfDocument, ImageFormat};
fn main() -> pdfluent::Result<()> {
let doc = PdfDocument::open("file.pdf")?;
let jpg = doc.render_page(1, 150, ImageFormat::Jpeg)?;
std::fs::write("page-1.jpg", jpg)?;
Ok(())
}Complete program, compiled against the published crate: Code on GitHub →
The same code, typed and run on screen. Watch on YouTube
Load the document.
use pdfluent::prelude::*;
let doc = PdfDocument::open("document.pdf")?;ToImagesOptions defaults to PNG; switch to Jpeg with with_format. JPEG quality is fixed at 90 in 1.0; user-configurable quality is tracked for a later release.
let opts = ToImagesOptions::new()
.with_dpi(150)
.with_format(ImageFormat::Jpeg);The {page} placeholder in the pattern is substituted with the 1-based page number.
let report = doc.to_images("page_{page}.jpg", opts)?;Render small preview images of every page in a PDF. Set a fixed width or height and PDFluent calculates the other dimension automatically.
use pdfluent::{PdfDocument, ImageFormat};
fn main() -> pdfluent::Result<()> {
let doc = PdfDocument::open("file.pdf")?;
for i in 1..=doc.page_count() {
let png = doc.render_page(i, 72, ImageFormat::Png)?;
std::fs::write(format!("thumb-{}.png", i), png)?;
}
Ok(())
}Complete program, compiled against the published crate: Code on GitHub →
The same code, typed and run on screen. Watch on YouTube
Load the document.
use pdfluent::prelude::*;
let doc = PdfDocument::open("slides.pdf")?;72 DPI is typical for thumbnails; for crisper previews, go up to 150 DPI.
let opts = ToImagesOptions::new()
.with_dpi(72)
.with_format(ImageFormat::Png);The {page} marker in the filename pattern is substituted with the 1-based page number.
let report = doc.to_images("thumb_{page}.png", opts)?;
for path in &report.paths {
println!("wrote {}", path.display());
}Limit the range with with_pages(from, to) using 1-based inclusive bounds.
let opts = ToImagesOptions::new()
.with_dpi(72)
.with_pages(1, 1);
let _ = doc.to_images("cover.png", opts)?;Embed JPEG, PNG, or WebP images at a specific position and size on any PDF page.
use pdfluent::PdfDocument;
use pdfluent::parity::{ImageInsert, InsertImageFormat};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut doc = PdfDocument::open("report.pdf")?;
let bytes = std::fs::read("logo.png")?;
doc.insert_image(ImageInsert::new(bytes, InsertImageFormat::Png, 1, 50.0, 700.0, 120.0, 40.0))?;
doc.save("with-logo.pdf")?;
Ok(())
}Image::from_file() reads JPEG, PNG, or WebP. Image::from_bytes() accepts the raw image bytes if you are reading from memory or a network source.
// Load the image bytes (PNG or JPEG)
let bytes = std::fs::read("logo.png")?;
println!("{} bytes loaded", bytes.len());insert_image takes the destination page in the ImageInsert itself. Pages are 1-based, so page 1 is the first page.
use pdfluent::parity::{ImageInsert, InsertImageFormat};
// Place on page 1. Pages are 1-based; coordinates are points from bottom-left.
let insert = ImageInsert::new(bytes.clone(), InsertImageFormat::Png, 1, 50.0, 700.0, 150.0, 60.0);PDF uses a coordinate system where (0, 0) is the bottom-left corner. Measurements are in points (1 pt = 1/72 inch). A4 is 595 x 842 pt, US Letter is 612 x 792 pt.
doc.insert_image(insert)?;Use ImagePosition::fit_width() to scale the image to a given width while preserving the aspect ratio.
use pdfluent::parity::{ImageInsert, InsertImageFormat};
// Insert with reduced opacity (e.g. a watermark-style logo)
doc.insert_image(
ImageInsert::new(bytes, InsertImageFormat::Png, 1, 50.0, 700.0, 150.0, 60.0)
.with_opacity(0.85),
)?;
doc.save("document-with-logo.pdf")?;