Add pdf export

main
Admin1312 2025-07-06 15:02:30 +02:00
parent ac26294893
commit c60397a60b
7 changed files with 79 additions and 21 deletions

View File

@ -4,4 +4,4 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
printpdf = "0.8.2" printpdf = { version = "0.8.2", features = [ "png", "jpeg"] }

BIN
image_example.pdf Normal file

Binary file not shown.

BIN
linux_antifa.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

View File

@ -3,7 +3,7 @@ use crate::stickers::*;
#[derive(Debug)] #[derive(Debug)]
pub struct Page { pub struct Page {
stickers: Vec<Sticker>, pub stickers: Vec<Sticker>,
} }
pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> { pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> {
@ -15,6 +15,10 @@ pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> {
}; };
for sticker_detail in sticker_details { for sticker_detail in sticker_details {
if !sticker_detail.path.is_file() {
panic!("Erreur d'ouverture du fichier : {:?}", sticker_detail.path)
}
let total_width = total_width(&config, sticker_detail.width); let total_width = total_width(&config, sticker_detail.width);
let total_height = total_height(&config, sticker_detail.height); let total_height = total_height(&config, sticker_detail.height);
@ -27,10 +31,6 @@ pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> {
while remaining > 0 { while remaining > 0 {
let index = current_page.stickers.len(); let index = current_page.stickers.len();
if index == stickers_per_page {
pages.push(current_page);
current_page = Page { stickers: vec![] };
}
let i = index / cols; let i = index / cols;
let j = index % cols; let j = index % cols;
@ -40,6 +40,14 @@ pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> {
current_page.stickers.push(create_sticker(sticker_detail.clone(), position_x, position_y)); current_page.stickers.push(create_sticker(sticker_detail.clone(), position_x, position_y));
remaining -= 1; remaining -= 1;
let index = current_page.stickers.len();
if index == stickers_per_page {
pages.push(current_page);
current_page = Page { stickers: vec![] };
}
} }
} }
@ -53,7 +61,7 @@ pub fn generate_page(sticker_details: Vec<StickerDetail>) -> Vec<Page> {
fn create_sticker(sticker_detail: StickerDetail, x: f64, y: f64) -> Sticker { fn create_sticker(sticker_detail: StickerDetail, x: f64, y: f64) -> Sticker {
Sticker { Sticker {
path: sticker_detail.path, path: sticker_detail.path,
position: (x, y), position: Position { x, y },
width: sticker_detail.width, width: sticker_detail.width,
height: sticker_detail.width height: sticker_detail.width
} }

View File

@ -1,24 +1,22 @@
use printstick::layout::generate_page; use printstick::layout::generate_page;
use printstick::stickers::StickerDetail; use printstick::stickers::StickerDetail;
use printstick::layout::Page; use printstick::layout::Page;
use printstick::pdf::generate_pdf;
use std::path::PathBuf;
fn main() { fn main() {
let stickers_order: Vec<StickerDetail> = vec![ let stickers_order: Vec<StickerDetail> = vec![
StickerDetail { StickerDetail {
number: 52, number: 52,
path: String::from("/test"), path: PathBuf::from("/Users/torpenn/projects/personal/PrintStick/linux_antifa.png"),
height: 50.0, height: 50.0,
width: 50.0 width: 50.0
}, }
StickerDetail {
number: 10,
path: String::from("/nouveau_sticker"),
height: 40.0,
width: 30.0
},
]; ];
let pages: Vec<Page> = generate_page(stickers_order); let pages: Vec<Page> = generate_page(stickers_order);
println!("Generated positions in one page: {:?}", pages); println!("Generated positions in one page: {:?}", pages);
generate_pdf(PathBuf::from("./image_example.pdf"), pages)
} }

View File

@ -1,3 +1,47 @@
// pub fn generate_pdf(output_path: &str, positions: Vec<(Mm, Mm)>, stickers: &[Sticker]) { use crate::layout::Page;
use printpdf::*;
use std::path::PathBuf;
// } pub fn generate_pdf(output_path: PathBuf, pages: Vec<Page>) {
let mut doc = PdfDocument::new("Planches");
let mut final_pages = Vec::new();
for page in pages {
let mut ops = Vec::new();
for sticker in page.stickers {
let image_bytes = std::fs::read(sticker.path).unwrap();
let image = RawImage::decode_from_bytes(&image_bytes, &mut Vec::new()).unwrap();
let image_id = doc.add_image(&image);
ops.push(Op::UseXobject {
id: image_id.clone(),
transform: XObjectTransform {
translate_x: Some(Mm(sticker.position.x as f32).into()),
translate_y: Some(Mm(sticker.position.y as f32).into()),
rotate: Some(XObjectRotation {
angle_ccw_degrees: 0.0,
rotation_center_x: Px(0),
rotation_center_y: Px(0),
}),
scale_x: Some(1.0),
scale_y: Some(1.0),
dpi: Some(300.0),
},
});
}
let page = PdfPage::new(Mm(420.0), Mm(297.0), ops);
final_pages.push(page)
}
let bytes = doc
.with_pages(final_pages)
.save(&PdfSaveOptions::default(), &mut Vec::new());
std::fs::write(output_path, bytes).unwrap();
println!("Created image_example.pdf");
}

View File

@ -1,17 +1,25 @@
use std::path::PathBuf;
// Use for one stickers // Use for one stickers
#[derive(Debug)] #[derive(Debug)]
pub struct Sticker { pub struct Sticker {
pub path: String, pub path: PathBuf,
pub position: (f64, f64), // (x, y) pub position: Position,
pub width: f64, pub width: f64,
pub height: f64 pub height: f64
} }
// User for many different sticker #[derive(Debug)]
pub struct Position {
pub x: f64,
pub y: f64
}
// Use for many different sticker
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StickerDetail { pub struct StickerDetail {
pub number: u32, pub number: u32,
pub path: String, pub path: PathBuf,
pub width: f64, pub width: f64,
pub height: f64, pub height: f64,
} }