Rust PDF渲染库pdfium-render的使用:高效解析与渲染PDF文件的Rust插件库

Rust PDF渲染库pdfium-render的使用:高效解析与渲染PDF文件的Rust插件库

pdfium-render 提供了对 Pdfium 的高级 Rust 接口,Pdfium 是 Google Chromium 项目使用的 C++ PDF 库。Pdfium 可以将 PDF 文件中的页面渲染为位图,加载、编辑和提取现有 PDF 文件中的文本和图像,以及从头创建新的 PDF 文件。

基本使用示例

use pdfium_render::prelude::*;

fn export_pdf_to_jpegs(path: &impl AsRef<Path>, password: Option<&str>) -> Result<(), PdfiumError> {
    // 将给定路径的PDF文件中的每一页渲染为单独的JPEG文件

    // 绑定到与Rust可执行文件相同目录中的Pdfium库
    let pdfium = Pdfium::default();

    // 从给定路径加载文档...
    let document = pdfium.load_pdf_from_file(path, password)?;

    // ...设置将应用于所有页面的渲染选项...
    let render_config = PdfRenderConfig::new()
        .set_target_width(2000)
        .set_maximum_height(2000)
        .rotate_if_landscape(PdfPageRenderRotation::Degrees90, true);

    // ...然后将每一页渲染为位图图像,将每个图像保存为JPEG文件
    for (index, page) in document.pages().iter().enumerate() {
        page.render_with_config(&render_config)?
            .as_image() // 将此页面渲染为image::DynamicImage...
            .into_rgb8() // ...然后转换为image::Image...
            .save_with_format(
                format!("test-page-{}.jpg", index), 
                image::ImageFormat::Jpeg
            ) // ...并保存到文件
            .map_err(|_| PdfiumError::ImageError)?;
    }

    Ok(())
}

完整示例代码

下面是一个更完整的示例,展示如何加载PDF、渲染页面并提取文本:

use pdfium_render::prelude::*;
use std::path::Path;

fn main() -> Result<(), PdfiumError> {
    // 初始化Pdfium库
    let pdfium = Pdfium::default();
    
    // 加载PDF文件
    let document = pdfium.load_pdf_from_file("example.pdf", None)?;
    
    // 遍历每一页
    for (i, page) in document.pages().iter().enumerate() {
        println!("处理第 {} 页", i + 1);
        
        // 渲染页面为图像
        let render_config = PdfRenderConfig::new()
            .set_target_width(1000);
            
        let image = page.render_with_config(&render_config)?
            .as_image()?
            .into_rgb8();
            
        image.save(format!("page-{}.png", i))?;
        
        // 提取页面文本
        let text = page.text()?;
        println!("提取的文本: {}", text.all());
        
        // 遍历页面对象
        for object in page.objects().iter() {
            match object.object_type() {
                PdfPageObjectType::Path => println!("找到路径对象"),
                PdfPageObjectType::Text => {
                    let text_obj = object.as_text_object()?;
                    println!("文本对象内容: {}", text_obj.text());
                },
                PdfPageObjectType::Image => println!("找到图像对象"),
                _ => {}
            }
        }
    }
    
    Ok(())
}

特性

pdfium-render 提供了以下可选特性:

  • bindings: 每次运行cargo build时使用cbindgen生成Rust绑定
  • image: 控制是否使用image crate提供页面和页面对象渲染功能
  • static: 启用绑定到静态链接的Pdfium构建
  • thread_safe: 通过互斥锁包装对Pdfium的访问以确保线程安全

安装

要使用这个库,可以在项目的Cargo.toml中添加:

[dependencies]
pdfium-render = "0.8.34"

或者运行cargo命令:

cargo add pdfium-render

1 回复

Rust PDF渲染库pdfium-render的使用指南

概述

pdfium-render是一个基于Google PDFium的Rust绑定库,用于高效解析和渲染PDF文件。它提供了强大的PDF处理能力,包括文本提取、页面渲染和文档操作等功能。

主要特性

  • 高性能PDF渲染
  • 跨平台支持
  • 文本提取和分析
  • 页面操作和转换
  • 支持多种图像输出格式

安装方法

在Cargo.toml中添加依赖:

[dependencies]
pdfium-render = "0.8"

基本使用方法

1. 加载PDF文件

use pdfium_render::prelude::*;

let pdfium = Pdfium::new(
    Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./"))
        .or_else(|_| Pdfium::bind_to_system_library())?,
);

let document = pdfium.load_pdf_from_file("example.pdf", None)?;

2. 获取文档信息

println!("页数: {}", document.pages().len());
println!("标题: {:?}", document.metadata().title());
println!("作者: {:?}", document.metadata().author());

3. 渲染PDF页面为图像

use image::DynamicImage;

let page = document.pages().get(0)?;
let render_config = PdfRenderConfig::new()
    .set_target_width(1000)
    .rotate_if_landscape(PdfBitmapRotation::Degrees90, true);

let image = page.render_with_config(&render_config)?;
let dynamic_image: DynamicImage = image.as_image()?;
dynamic_image.save("page0.png")?;

4. 提取文本内容

let text = page.text()?;
println!("第一页文本内容:\n{}", text.all());

5. 高级使用:批量处理页面

for (index, page) in document.pages().iter().enumerate() {
    let text = page.text()?;
    println!("第{}页文本长度: {}", index + 1, text.len());
    
    let image = page.render_with_config(&PdfRenderConfig::new())?;
    image.as_image()?.save(format!("page{}.png", index))?;
}

完整示例代码

use pdfium_render::prelude::*;
use image::DynamicImage;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 初始化PDFium实例
    let pdfium = Pdfium::new(
        Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./"))
            .or_else(|_| Pdfium::bind_to_system_library())?,
    );

    // 2. 加载PDF文件
    let document = pdfium.load_pdf_from_file("example.pdf", None)?;
    
    // 3. 打印文档信息
    println!("=== 文档信息 ===");
    println!("页数: {}", document.pages().len());
    println!("标题: {:?}", document.metadata().title());
    println!("作者: {:?}", document.metadata().author());
    
    // 4. 渲染第一页为图像
    println!("\n正在渲染第一页...");
    let page = document.pages().get(0)?;
    let render_config = PdfRenderConfig::new()
        .set_target_width(1000)
        .rotate_if_landscape(PdfBitmapRotation::Degrees90, true);

    let image = page.render_with_config(&render_config)?;
    let dynamic_image: DynamicImage = image.as_image()?;
    dynamic_image.save("page0.png")?;
    println!("已保存第一页图像到 page0.png");
    
    // 5. 提取第一页文本
    println!("\n=== 第一页文本内容 ===");
    let text = page.text()?;
    println!("{}", text.all());
    
    // 6. 批量处理所有页面
    println!("\n开始批量处理所有页面...");
    for (index, page) in document.pages().iter().enumerate() {
        println!("\n处理第{}页...", index + 1);
        
        // 提取文本
        let text = page.text()?;
        println!("文本长度: {}", text.len());
        
        // 渲染并保存图像
        let image = page.render_with_config(&PdfRenderConfig::new())?;
        let output_path = format!("page{}.png", index);
        image.as_image()?.save(&output_path)?;
        println!("已保存图像到 {}", output_path);
    }
    
    Ok(())
}

注意事项

  1. 需要提前安装PDFium库或提供其路径
  2. 处理大文件时注意内存使用
  3. 多线程环境下需要适当同步

平台支持

pdfium-render支持以下平台:

  • Windows
  • macOS
  • Linux

性能优化建议

  • 对于批量操作,复用Pdfium实例
  • 根据需要调整渲染质量
  • 使用合适的页面缓存策略

错误处理

match pdfium.load_pdf_from_file("example.pdf", None) {
    Ok(doc) => {
        // 处理文档
    },
    Err(e) => {
        eprintln!("加载PDF失败: {}", e);
    }
}

这个库为Rust开发者提供了强大的PDF处理能力,适合需要高性能PDF渲染和解析的应用场景。

回到顶部