parent
7abd0c2afd
commit
db8407c1c3
6 changed files with 174 additions and 115 deletions
@ -1,70 +1,114 @@ |
|||||||
use printpdf::*; |
// use printpdf::*;
|
||||||
use std::path::Path; |
use std::path::Path; |
||||||
|
use quick_xml::Reader; |
||||||
|
use quick_xml::events::{Event, BytesStart}; |
||||||
|
use std::collections::HashSet; |
||||||
|
|
||||||
|
|
||||||
pub fn imageToPdf(path: String) -> Result<String, String> { |
// pub fn imageToPdf(path: String) -> Result<String, String> {
|
||||||
let mut doc = PdfDocument::new("image_to_pdf"); |
// let mut doc = PdfDocument::new("image_to_pdf");
|
||||||
|
|
||||||
let image_bytes = std::fs::read(&path).map_err(|e| e.to_string())?; |
// let image_bytes = std::fs::read(&path).map_err(|e| e.to_string())?;
|
||||||
let image = RawImage::decode_from_bytes(&image_bytes, &mut Vec::new()).unwrap(); |
// let image = RawImage::decode_from_bytes(&image_bytes, &mut Vec::new()).unwrap();
|
||||||
|
|
||||||
|
|
||||||
let mut ops = Vec::new(); |
// let mut ops = Vec::new();
|
||||||
|
|
||||||
// In the PDF, an image is an `XObject`, identified by a unique `ImageId`
|
// // In the PDF, an image is an `XObject`, identified by a unique `ImageId`
|
||||||
let image_xobject_id = doc.add_image(&image); |
// let image_xobject_id = doc.add_image(&image);
|
||||||
|
|
||||||
// Calculate image size in points (1 point = 1/72 inch)
|
// // Calculate image size in points (1 point = 1/72 inch)
|
||||||
let dpi = 300.0; |
// let dpi = 300.0;
|
||||||
let output_width= 105.0; // A6 width in mm
|
// let output_width= 105.0; // A6 width in mm
|
||||||
let output_height = 148.0; // A6 height in mm
|
// let output_height = 148.0; // A6 height in mm
|
||||||
let mm_to_pt = dpi / 25.4; // Conversion factor
|
// let mm_to_pt = dpi / 25.4; // Conversion factor
|
||||||
let width_pt = output_width * mm_to_pt; |
// let width_pt = output_width * mm_to_pt;
|
||||||
let height_pt = output_height * mm_to_pt; |
// let height_pt = output_height * mm_to_pt;
|
||||||
|
|
||||||
println!("Image size in pixels: {}x{}", image.width, image.height); |
// println!("Image size in pixels: {}x{}", image.width, image.height);
|
||||||
println!("Dest Image size in points: {}x{}", width_pt, height_pt); |
// println!("Dest Image size in points: {}x{}", width_pt, height_pt);
|
||||||
|
|
||||||
// Place the image at (0,0) with the calculated size
|
// // Place the image at (0,0) with the calculated size
|
||||||
ops.push(Op::UseXobject { |
// ops.push(Op::UseXobject {
|
||||||
id: image_xobject_id.clone(), |
// id: image_xobject_id.clone(),
|
||||||
transform: XObjectTransform { |
// transform: XObjectTransform {
|
||||||
translate_x: Some(Pt(0.0)), |
// translate_x: Some(Pt(0.0)),
|
||||||
translate_y: Some(Pt(0.0)), |
// translate_y: Some(Pt(0.0)),
|
||||||
dpi: Some(dpi), |
// dpi: Some(dpi),
|
||||||
..Default::default() |
// ..Default::default()
|
||||||
}, |
// },
|
||||||
|
|
||||||
}); |
// });
|
||||||
|
|
||||||
let save_options= PdfSaveOptions { |
// let save_options= PdfSaveOptions {
|
||||||
optimize: false, |
// optimize: false,
|
||||||
image_optimization: Some(ImageOptimizationOptions { |
// image_optimization: Some(ImageOptimizationOptions {
|
||||||
quality: Some(1.0), |
// quality: Some(1.0),
|
||||||
auto_optimize: Some(false), |
// auto_optimize: Some(false),
|
||||||
format: Some(ImageCompression::None), |
// format: Some(ImageCompression::None),
|
||||||
..ImageOptimizationOptions::default() |
// ..ImageOptimizationOptions::default()
|
||||||
}), |
// }),
|
||||||
..Default::default() |
// ..Default::default()
|
||||||
}; |
// };
|
||||||
|
|
||||||
|
|
||||||
let page1 = PdfPage::new(Mm(output_width), Mm(output_height), ops); |
// let page1 = PdfPage::new(Mm(output_width), Mm(output_height), ops);
|
||||||
let pdf_bytes: Vec<u8> = doc |
// let pdf_bytes: Vec<u8> = doc
|
||||||
.with_pages(vec![page1]) |
// .with_pages(vec![page1])
|
||||||
.save(&save_options, &mut Vec::new()); |
// .save(&save_options, &mut Vec::new());
|
||||||
|
|
||||||
let pdf_path = Path::new(&path).with_extension("pdf"); |
// let pdf_path = Path::new(&path).with_extension("pdf");
|
||||||
|
|
||||||
match std::fs::write(&pdf_path, pdf_bytes) { |
// match std::fs::write(&pdf_path, pdf_bytes) {
|
||||||
Ok(_) => { |
// Ok(_) => {
|
||||||
let abs_path = std::fs::canonicalize(&pdf_path) |
// let abs_path = std::fs::canonicalize(&pdf_path)
|
||||||
.map(|p| p.display().to_string()) |
// .map(|p| p.display().to_string())
|
||||||
.unwrap_or_else(|_| pdf_path.display().to_string()); |
// .unwrap_or_else(|_| pdf_path.display().to_string());
|
||||||
println!("PDF written successfully to {}", abs_path); |
// println!("PDF written successfully to {}", abs_path);
|
||||||
Ok(abs_path) |
// Ok(abs_path)
|
||||||
}, |
// },
|
||||||
Err(e) => Err(format!("Failed to write PDF: {}", e)), |
// Err(e) => Err(format!("Failed to write PDF: {}", e)),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_output_quality_options(xml: &str) -> Vec<String> { |
||||||
|
let mut reader = Reader::from_str(xml); |
||||||
|
// reader.trim_text(true);
|
||||||
|
|
||||||
|
// let mut buf = Vec::new();
|
||||||
|
let mut inside_target_feature = false; |
||||||
|
let mut inside_option = false; |
||||||
|
let mut current_option_name = String::new(); |
||||||
|
let mut results = HashSet::new(); |
||||||
|
|
||||||
|
loop { |
||||||
|
match reader.read_event() { |
||||||
|
Ok(Event::Start(ref e)) => { |
||||||
|
if e.name().as_ref() == b"psf:Feature" { |
||||||
|
if let Some(attr) = e.attributes().filter_map(Result::ok).find(|a| a.key.as_ref() == b"name") { |
||||||
|
if attr.unescape_value().unwrap() == "psk:PageOutputQuality" { |
||||||
|
inside_target_feature = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} else if inside_target_feature && e.name().as_ref() == b"psf:Option" { |
||||||
|
if let Some(attr) = e.attributes().filter_map(Result::ok).find(|a| a.key.as_ref() == b"name") { |
||||||
|
results.insert(attr.unescape_value().unwrap().to_string()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
Ok(Event::End(ref e)) if e.name().as_ref() == b"psf:Feature" => { |
||||||
|
inside_target_feature = false; |
||||||
|
} |
||||||
|
Ok(Event::Eof) => break, |
||||||
|
_ => {} |
||||||
|
} |
||||||
|
// buf.clear();
|
||||||
} |
} |
||||||
} |
|
||||||
|
|
||||||
|
let mut vec: Vec<String> = results.into_iter().collect(); |
||||||
|
vec.sort(); |
||||||
|
vec |
||||||
|
} |
||||||
|
|||||||
@ -0,0 +1,14 @@ |
|||||||
|
export const AvailableQualities=[ |
||||||
|
{ "name": "ns0000:Draft", "displayname": "草稿" }, |
||||||
|
{ "name": "ns0000:DraftVivid", "displayname": "草稿鮮豔" }, |
||||||
|
{ "name": "ns0000:Standard", "displayname": "標準" }, |
||||||
|
{ "name": "ns0000:StandardVivid", "displayname": "標準鮮豔" }, |
||||||
|
{ "name": "ns0000:HighQuality", "displayname": "高" }, |
||||||
|
{ "name": "ns0000:AdvancedSetting", "displayname": "自訂" } |
||||||
|
]; |
||||||
|
|
||||||
|
|
||||||
|
export const Scales=[ |
||||||
|
|
||||||
|
] |
||||||
|
|
||||||
Loading…
Reference in new issue