How to use `Page`'s `to_svg` method?
namespaceYcZ opened this issue · 0 comments
namespaceYcZ commented
The program panic when I try coverting a page to svg(STATUS_ACCESS_VIOLATION):
use std::fmt::Display;
use std::io::Write;
use std::path::Path;
use mupdf::document::Document;
use mupdf::{Matrix, Page};
/// Renders each page in the PDF file at the given path to a separate JPEG file.
pub fn export_pdf_to_images<P: Display>(
document: Document,
to_render: &[i32],
rename_fn: &impl Fn(i32) -> P,
image_path: &Path,
) -> Result<Vec<i32>, std::io::Error> {
let mut res = vec![];
if !image_path.exists() {
std::fs::create_dir_all(image_path).map_err(crate::common::map_std_io_err)?;
}
let matrix = Matrix::IDENTITY;
tracing::debug!("render config created: {matrix:?}");
if to_render.is_empty() {
// ... then render each page to a bitmap image, saving each image to a JPEG file.
for (index, page) in document
.pages()
.map_err(crate::common::map_std_io_err)?
.enumerate()
{
self::export_pdf_page(
page.map_err(crate::common::map_std_io_err)?,
image_path,
rename_fn,
index as i32,
&matrix,
&mut res,
)?;
}
} else {
for page_no in to_render {
self::export_pdf_page(
document
.load_page(*page_no)
.map_err(crate::common::map_std_io_err)?,
image_path,
rename_fn,
*page_no,
&matrix,
&mut res,
)?;
}
}
Ok(res)
}
fn export_pdf_page<P: Display>(
page: Page,
image_path: &Path,
rename_fn: &impl Fn(i32) -> P,
page_no: i32,
ctm: &Matrix,
res: &mut Vec<i32>,
) -> std::io::Result<()> {
let mut this_path = image_path.to_path_buf();
let image_file_name = format!("{}.svg", rename_fn(page_no));
tracing::debug!("image name: {image_file_name}");
this_path.push(image_file_name);
tracing::debug!("save image to: {this_path:?}");
let bounds = page.bounds().map_err(crate::common::map_std_io_err)?;
tracing::debug!("pdf bounds: {bounds}");
let svg = page.to_svg(ctm).map_err(crate::common::map_std_io_err)?;
tracing::debug!("page-{page_no} rendered!");
let mut file = std::fs::File::create(this_path)?;
tracing::debug!("file created!");
file.write_all(svg.as_bytes())?;
tracing::debug!("file written!");
res.push(page_no);
Ok(())
}
mod tests {
#[test]
fn test_save() -> std::io::Result<()> {
let log_guards = crate::config::log_config::init_tracing();
let document = mupdf::document::Document::open(
"D:/Storage/SomePdf.pdf",
)
.map_err(crate::common::map_std_io_err)?;
tracing::debug!(
"document loaded: {} pages",
document
.page_count()
.map_err(crate::common::map_std_io_err)?
);
super::export_pdf_to_images(
document,
&[1, 2],
&|page_no| format!("test-page-{page_no}"),
"./external/output/pics".as_ref(),
)?;
drop(log_guards);
Ok(())
}
}
test_save:
(As you can see, Page
's bounds
method was invoked successfully, so I think the mupdf lib was build correctly)
Environment
- OS: Windows 11 version 22H2
- Architecture: Intel x86_64
- Rust version: 1.73.0
- mupdf-rs version: 0.4.1