免费 C++ 库,用于将 PDF 页面渲染为图像并提取文本。
开源 C++ PDF 处理库,可通过 C++ API 将 PDF 页面渲染为图像、提取文本、处理受密码保护的 PDF,并访问文档元数据。
什么是 PDFium-Render?
在 C++ 应用程序中处理和渲染 PDF 长期以来都是一个复杂的挑战,通常需要昂贵的商业许可证或笨重的开源工具。现在有了 PDFium-Render,这是一款现代的、仅头文件的 C++ 包装库,能够以直观且简洁的接口将 Google 的 PDFium 引擎的强大功能引入您的项目。PDFium-render 是针对 PDFium 的安全、符合惯用风格的 Rust 绑定,PDFium 同时也是驱动 Google Chrome 和 Mozilla Firefox 的 PDF 渲染引擎。该库由 ajrcarey 创建并维护,为开发者提供了强大的工具集,可将 PDF 页面渲染为图像、提取文本、操作 PDF 结构以及访问文档元数据——所有这些都利用了 Rust 的内存安全保证。
与许多仅专注于创建或基础解析的 PDF 库不同,PDFium-Render 在以像素级精确度渲染 PDF 内容方面表现出色,适用于需要显示、转换或处理现有 PDF 文档的应用程序。它支持多种基础和高级功能来处理 PDF 文档,例如渲染 PDF 文件和页面、文本提取与分析、处理文档元数据、访问和操作页面对象、处理受密码保护的 PDF 等。pdfium-render 最大的优势之一是跨平台支持。该库在 Windows、macOS 和 Linux 上无缝运行,抽象了 PDFium 二进制文件的平台特定差异。无论您是构建文档查看器、自动化 PDF 处理工作流,还是从 PDF 中提取数据,pdfium-render 都提供您所需的工具。
PDFium-Render 入门指南
推荐的安装 PDFium-Render 的方式是使用 CMake。请使用以下命令进行顺利安装。
通过 GitHub 安装 PDFium-Render
vcpkg install pdfium-render
通过 GitHub 安装 PDFium-Render
Git clone https://github.com/ajrcarey/pdfium-render.git 您也可以手动安装;直接从 GitHub 仓库下载最新的发布文件。
通过 C++ 实现高保真 PDF 渲染
开源的 PDFium-Render 库的主要优势在于其渲染能力。它可以将 PDF 页面转换为高质量的光栅图像,支持包括 PNG、JPEG 和 BMP 在内的多种输出格式。渲染引擎能够以与 Chrome PDF 查看器相同的精确度处理透明度、渐变、嵌入字体和矢量图形等复杂的 PDF 特性。下面是一个简单示例,展示软件开发者如何在 C++ 应用程序中将特定页面渲染为 PNG 图像格式。
如何使用 C++ 将特定 PDF 页面渲染为 PNG 格式?
use pdfium_render::prelude::*;
fn render_pdf_page() -> Result<(), PdfiumError> {
// Initialize PDFium library
let pdfium = Pdfium::new(
Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./"))
.or_else(|_| Pdfium::bind_to_system_library())?
);
// Load a PDF document
let document = pdfium.load_pdf_from_file("sample.pdf", None)?;
// Get the first page
let page = document.pages().get(0)?;
// Render the page to a bitmap at 300 DPI
let bitmap = page.render_with_config(
&PdfRenderConfig::new()
.set_target_width(2480) // 300 DPI for 8.27 inches
.set_target_height(3508) // 300 DPI for 11.69 inches
)?;
// Save as PNG
bitmap.as_image().as_rgba8().unwrap()
.save("output.png")?;
Ok(())
}
通过 C++ 库进行文本提取和分析
除了渲染功能外,PDFium-Render 库还提供了全面的文本提取能力。文本提取 API 直观且强大。软件开发者可以从单个页面提取文本、搜索特定字符串,甚至仅通过几行代码就获取字符级别的位置信息——这对于实现文本选择或高亮等功能至关重要。下面的示例展示了软件开发者如何在 C++ 应用程序中从特定 PDF 页面区域提取文本。
如何通过 C++ API 从特定 PDF 页面区域提取文本?
use pdfium_render::prelude::*;
fn extract_text_from_page() -> Result<(), PdfiumError> {
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("document.pdf", None)?;
let page = document.pages().get(0)?;
// Extract all text from the page
let text = page.text()?;
let all_text = text.all();
println!("Page text: {}", all_text);
// Search for specific text
let search_results = text.search("important", true, false)?;
for result in search_results {
println!("Found at index: {}", result.start_index());
}
// Get text in a specific rectangular area
let rect = PdfRect::new(100.0, 100.0, 300.0, 200.0);
let bounded_text = text.bounded(rect)?;
println!("Text in region: {}", bounded_text);
Ok(())
}
使用 C++ 处理受密码保护的 PDF 文档
在处理文档时,安全至关重要。PDFium-Render 能够无缝处理受密码保护的 PDF,支持用户密码和所有者密码。库会透明地进行身份验证,如果密码错误或 PDF 存在限制导致某些操作无法执行,会返回相应的错误。下面是一个非常有用的示例,展示如何在 C++ 应用程序中处理受密码保护的 PDF 文档。
如何通过 C++ API 打开并加载受密码保护的 PDF 文档?
fn open_encrypted_pdf() -> Result<(), PdfiumError> {
let pdfium = Pdfium::new(
Pdfium::bind_to_library(Pdfium::pdfium_platform_library_name_at_path("./"))
.or_else(|_| Pdfium::bind_to_system_library())?
);
// Attempt to load with password
let document = pdfium.load_pdf_from_file(
"confidential.pdf",
Some("secret_password")
)?;
println!("Successfully opened encrypted PDF");
println!("Pages: {}", document.pages().len());
Ok(())
}
使用 C++ 操作 PDF 元数据和属性
了解 PDF 的结构对许多应用程序至关重要。开源的 PDFium-Render 库提供对文档元数据、页数、尺寸以及其他属性的完整访问。这一功能对于构建文档管理系统、PDF 验证器或任何需要根据属性对 PDF 进行分类或处理的应用程序都极为宝贵。下面的代码示例演示了程序员如何轻松地处理 PDF 文档的元数据并访问各种属性。
如何通过 C++ API 处理 PDF 文档的元数据?
fn inspect_document_metadata() -> Result<(), PdfiumError> {
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("report.pdf", None)?;
// Access document metadata
let metadata = document.metadata();
println!("Title: {}", metadata.title().unwrap_or("Untitled"));
println!("Author: {}", metadata.author().unwrap_or("Unknown"));
println!("Creator: {}", metadata.creator().unwrap_or("Unknown"));
println!("Producer: {}", metadata.producer().unwrap_or("Unknown"));
// Get page count
let page_count = document.pages().len();
println!("Total pages: {}", page_count);
// Inspect individual page properties
for (index, page) in document.pages().iter().enumerate() {
let width = page.width();
let height = page.height();
println!("Page {}: {}x{} points", index + 1, width.value, height.value);
}
Ok(())
}