本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2024/10/17/rust-with-pdfium-to-convert-pdf-to-png/
最近有几张电子发票要报保险,但是腾讯微保上传发票需要上传图片,想着直接转一下,然后手机上各种APP试了一圈要么要收费,要么只能免费转第一页,不巧的是我这几张发票有明细表,都是两页的。网页版本有各种免费的,但是始终比较担心安全性,无奈只有自己搞一下。
PDF的标准很复杂,自己实现显然不是最佳选择。PDFium 是一个开源的 PDF 渲染引擎,由 Google 开发和维护。它用于解析和渲染 PDF 文档,广泛应用于 Chrome 浏览器和其他项目。PDFium 提供高效的 PDF 处理功能,包括文本提取、注释、表单填充和页面渲染,支持多平台,当然就包括了Android。
开源社区有Rust的绑定,我们可以直接使用,我这里版本用的6666,社区也有预构建文件可以直接下载。
这里参考官方例子,唯一的区别的改动是从单页导出改为全部页面导出
pub struct PdfToImageResult {
pub image_path: String,
}
pub fn export_pdf_to_jpegs(path: String, out_dir: String) -> PdfToImageResult {
let p = Pdfium::default();
let document = p.load_pdf_from_file(&path, Option::None).unwrap();
let render_config = PdfRenderConfig::new()
.set_target_width(2000)
.set_maximum_height(2000)
.rotate_if_landscape(PdfPageRenderRotation::Degrees90, true);
let mut images: Vec<RgbaImage> = Vec::new();
let mut total_width = 0;
let mut total_height = 0;
for page in document.pages().iter() {
let image = page
.render_with_config(&render_config)
.unwrap()
.as_image()
.to_rgba8();
total_width = total_width.max(image.width());
total_height += image.height();
images.push(image);
}
let mut combined_image = RgbaImage::new(total_width, total_height);
let mut y_offset = 0;
for image in images {
combined_image.copy_from(&image, 0, y_offset).unwrap();
y_offset += image.height();
}
let output_path = Path::new(&out_dir)
.join(Path::new(&path).file_stem().unwrap())
.with_extension("png");
let file = File::create(&output_path).unwrap();
let mut writer = BufWriter::new(file);
DynamicImage::ImageRgba8(combined_image)
.write_to(&mut writer, ImageFormat::Png)
.unwrap();
return PdfToImageResult {
image_path: output_path.to_str().unwrap().to_string(),
};
}
链接
https://github.com/bblanchon/pdfium-binaries
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
转载自夜明的孤行灯
本文链接地址: https://www.huangyunkun.com/2024/10/17/rust-with-pdfium-to-convert-pdf-to-png/