manual_image_extraction/
manual_image_extraction.rs1use base64::Engine;
7use base64::engine::general_purpose;
8use pptx_to_md::{ImageHandlingMode, ParserConfig, PresentationContainer, Result};
9use std::fs::File;
10use std::io::Write;
11use std::path::Path;
12use std::{env, fs};
13
14fn main() -> Result<()> {
15 let args: Vec<String> = env::args().collect();
16 let Some(input_path) = args.get(1) else {
17 eprintln!(
18 "Usage: cargo run --example manual_image_extraction <presentation.pptx|presentation.odp>"
19 );
20 return Ok(());
21 };
22
23 println!("Processing presentation: {input_path}");
24
25 let config = ParserConfig::builder()
27 .extract_images(true)
28 .compress_images(true)
29 .quality(75)
30 .image_handling_mode(ImageHandlingMode::Manually)
31 .build();
32
33 let mut container = PresentationContainer::open(Path::new(input_path), config)?;
34
35 let slides = container.parse_all()?;
37
38 println!("Found {} slides", slides.len());
39
40 let mut md_file = File::create("output.md")?;
42
43 let output_dir = "extracted_images";
45 fs::create_dir_all(output_dir)?;
46
47 let mut image_count = 1;
48
49 for slide in slides {
51 writeln!(md_file, "{}", slide.convert_to_md()?)?;
52
53 if let Some(images) = slide.load_images_manually() {
55 for image in images {
56 let image_data = general_purpose::STANDARD
58 .decode(image.base64_content.clone())
59 .expect("parser returned invalid base64 image data");
60
61 let ext = if slide.config.compress_images {
63 "jpg".to_string()
64 } else {
65 slide.get_image_extension(&image.img_ref.target.clone())
66 };
67
68 let file_name = format!(
70 "slide{}_image{}_{}",
71 slide.slide_number, image_count, &image.img_ref.id
72 );
73
74 let output_path = format!("{}/{}.{}", output_dir, &file_name, ext);
76 fs::write(&output_path, image_data)?;
77 println!("Saved image to {}", output_path);
78
79 writeln!(
81 md_file,
82 "",
83 file_name, ext, image.base64_content
84 )?;
85
86 image_count += 1;
87 }
88 }
89 }
90
91 println!("All slides converted successfully!");
92
93 Ok(())
94}