preset/
preset.rs

1use std::{collections::HashMap, fs, io::Write};
2
3use si_img::{SiFont, SiImage, SiPreset, TextOptions};
4
5fn main() {
6    // Create the preset
7    let preset = SiPreset::new(Box::new(|img, vals| {
8        let new_img = img.clone();
9        // img is the full image
10        println!("Dimensions: {}x{}", img.width(), img.height());
11        println!("Values: {:?}", vals);
12        // Get the font
13        let font = match vals.get("font") {
14            Some(font) => {
15                // Do type checking
16                if font.type_id() == std::any::TypeId::of::<SiFont>() {
17                    // Downcast it
18                    font.downcast_ref::<SiFont>().unwrap()
19                } else {
20                    panic!(
21                        "Expected type: {:?}\nFound type: {:?}",
22                        std::any::TypeId::of::<SiFont>(),
23                        font.type_id()
24                    );
25                }
26            }
27            None => panic!("No font provided"),
28        };
29        // Render something on the image with that font
30        // Get the title
31        let title = match vals.get("title") {
32            Some(title) => {
33                // Do type checking
34                if title.type_id() == std::any::TypeId::of::<String>() {
35                    // Downcast it
36                    title.downcast_ref::<String>().unwrap()
37                } else {
38                    panic!(
39                        "Expected type: {:?}\nFound type: {:?}",
40                        std::any::TypeId::of::<String>(),
41                        title.type_id()
42                    );
43                }
44            }
45            None => panic!("No title provided"),
46        };
47        let text_options = TextOptions::default();
48        // Render it
49        new_img.render_text(title, 64.0, 480.0, 254.0, None, font, &text_options)
50    }));
51
52    // Use it
53    // Create the image
54    let mut img = SiImage::from_network("https://res.cloudinary.com/zype/image/upload/regraphic");
55    // Create the font
56    let font = SiFont::from_network(
57        "https://github.com/Zype-Z/ShareImage.js/raw/main/assets/fonts/sirin-stencil.ttf",
58    );
59    let font_val: Box<dyn std::any::Any> = Box::new(font);
60    let title_val: Box<dyn std::any::Any> = Box::new("Hello, World!".to_string());
61    let values: HashMap<String, Box<dyn std::any::Any>> = HashMap::from([
62        ("font".to_string(), font_val),
63        ("title".to_string(), title_val),
64    ]);
65    img.load_preset(preset, values);
66    let mut file = fs::OpenOptions::new()
67        .create(true) // To create a new file
68        .write(true)
69        // either use the ? operator or unwrap since it returns a Result
70        .open("out.png")
71        .unwrap();
72    file.write_all(&img.to_bytes()).unwrap();
73}