experimental SVG-based video rendering engine made for music videos. React to MIDI or arbitrary signals from your DAW through "probe" VSTs
at main 71 lines 2.1 kB view raw
1use anyhow::Result; 2use measure_time::debug_time; 3use resvg::usvg; 4use std::sync::Arc; 5 6pub fn create_pixmap(width: u32, height: u32) -> tiny_skia::Pixmap { 7 debug_time!("create_pixmap"); 8 tiny_skia::Pixmap::new(width, height).expect("Failed to create pixmap") 9} 10 11pub fn paint_svg_on_pixmap( 12 pixmap: tiny_skia::PixmapMut<'_>, 13 svg_contents: &str, 14 canvas_dimensions: (usize, usize), 15 fontdb: &Option<Arc<usvg::fontdb::Database>>, 16) -> Result<()> { 17 debug_time!("paint_svg_on_pixmap"); 18 let parsed_svg = &svg_to_usvg_tree(svg_contents, fontdb)?; 19 20 usvg_tree_to_pixmap(canvas_dimensions, pixmap, parsed_svg); 21 22 Ok(()) 23} 24 25pub fn usvg_tree_to_pixmap( 26 canvas_dimensions: (usize, usize), 27 mut pixmap_mut: tiny_skia::PixmapMut<'_>, 28 parsed_svg: &resvg::usvg::Tree, 29) { 30 debug_time!("usvg_tree_to_pixmap"); 31 32 let (canvas_width, canvas_height) = canvas_dimensions; 33 let (target_width, target_height) = (pixmap_mut.width(), pixmap_mut.height()); 34 35 resvg::render( 36 parsed_svg, 37 tiny_skia::Transform::from_scale( 38 target_width as f32 / canvas_width as f32, 39 target_height as f32 / canvas_height as f32, 40 ), 41 &mut pixmap_mut, 42 ); 43} 44 45pub fn svg_to_usvg_tree( 46 svg: &str, 47 fontdb: &Option<Arc<usvg::fontdb::Database>>, 48) -> anyhow::Result<resvg::usvg::Tree> { 49 debug_time!("svg_to_usvg_tree"); 50 Ok(resvg::usvg::Tree::from_str( 51 svg, 52 &match fontdb { 53 Some(fontdb) => resvg::usvg::Options { 54 fontdb: fontdb.clone(), 55 ..Default::default() 56 }, 57 None => resvg::usvg::Options::default(), 58 }, 59 )?) 60} 61 62pub fn pixmap_to_png_data(pixmap: tiny_skia::Pixmap) -> anyhow::Result<Vec<u8>> { 63 debug_time!("pixmap_to_png_data"); 64 Ok(pixmap.encode_png()?) 65} 66 67pub fn write_png_data(data: Vec<u8>, at: &str) -> anyhow::Result<()> { 68 debug_time!("write_png_data"); 69 std::fs::write(at, data)?; 70 Ok(()) 71}