Could someone please explain to me why the resulting PNG file is blank?
pub fn render_svg_directly(svg_data: &str) -> Option<Pixmap> {
println!("svg_dat: {}", svg_data);
let opt = Options::default();
let rtree = Tree::from_str(svg_data, &opt).ok()?;
let pixmap_size = rtree.size;
let mut pixmap = Pixmap::new(pixmap_size.width() as u32, pixmap_size.height() as u32)?;
resvg::render(&rtree, tiny_skia::Transform::identity(), &mut pixmap.as_mut());
pixmap.save_png("test_output.png").expect("Failed to save pixmap to PNG");
Some(pixmap)
}
let svg_data = fs::read_to_string("../test.svg").expect("Failed to read SVG file");
let pixmap = plutonium::render_svg_directly(&svg_data).expect("Failed to render SVG");
output:
zeke plutonium_tester$ cargo run
Compiling plutonium v0.1.0 (/Users/zeke/dev/plutonium_farm/plutonium)
Compiling plutonium_tester v0.1.0 (/Users/zeke/dev/plutonium_farm/plutonium_tester)
Finished dev [unoptimized + debuginfo] target(s) in 1.18s
Running `target/debug/plutonium_tester`
svg_dat: <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
<style type="text/css">
.st0{fill:#92278F;stroke:#9E1F63;stroke-miterlimit:10;}
</style>
<rect class="st0" width="100" height="100"/>
</svg>
rtree: Tree { size: Size { width: NonZeroPositiveF32(FiniteF32(100.0)), height: NonZeroPositiveF32(FiniteF32(100.0)) }, view_box: ViewBox { rect: NonZeroRect { left: 0.0, top: 0.0, right: 100.0, bottom: 100.0 }, aspect: AspectRatio { defer: false, align: XMidYMid, slice: false } }, root: Group { id: "", transform: Transform { sx: 1.0, kx: 0.0, ky: 0.0, sy: 1.0, tx: 0.0, ty: 0.0 }, abs_transform: Transform { sx: 1.0, kx: 0.0, ky: 0.0, sy: 1.0, tx: 0.0, ty: 0.0 }, opacity: NormalizedF32(FiniteF32(1.0)), blend_mode: Normal, isolate: false, clip_path: None, mask: None, filters: [], bounding_box: None, stroke_bounding_box: None, layer_bounding_box: None, children: [Path(Path { id: "", visibility: Visible, fill: Some(Fill { paint: Color(Color { red: 146, green: 39, blue: 143 }), opacity: NormalizedF32(FiniteF32(1.0)), rule: NonZero }), stroke: Some(Stroke { paint: Color(Color { red: 158, green: 31, blue: 99 }), dasharray: None, dashoffset: 0.0, miterlimit: StrokeMiterlimit(10.0), opacity: NormalizedF32(FiniteF32(1.0)), width: NonZeroPositiveF32(FiniteF32(1.0)), linecap: Butt, linejoin: Miter }), paint_order: FillAndStroke, rendering_mode: GeometricPrecision, data: Path { segments: "M 0 0 L 100 0 L 100 100 L 0 100 Z", bounds: Rect { left: 0.0, top: 0.0, right: 100.0, bottom: 100.0 } }, abs_transform: Transform { sx: 1.0, kx: 0.0, ky: 0.0, sy: 1.0, tx: 0.0, ty: 0.0 }, bounding_box: None, stroke_bounding_box: None })] } }
I have tried different SVGs from both inkscape and illustrator formats.
You must call postprocess after parsing the Tree as stated in the documentation:
Must be called after parsing a usvg::Tree.
Here is the fixed render_svg_directly function:
pub fn render_svg_directly(svg_data: &str) -> Option<Pixmap> {
println!("svg_dat: {}", svg_data);
let opt = Options::default();
let mut rtree = Tree::from_str(svg_data, &opt).ok()?;
rtree.postprocess(PostProcessingSteps::default(), &fontdb::Database::new());
let pixmap_size = rtree.size;
let mut pixmap = Pixmap::new(pixmap_size.width() as u32, pixmap_size.height() as u32)?;
resvg::render(&rtree, tiny_skia::Transform::identity(), &mut pixmap.as_mut());
pixmap.save_png("test_output.png").expect("Failed to save pixmap to PNG");
Some(pixmap)
}
Note however that this will only work if the SVG does not contain inline text, otherwise you would need to transform that text into paths in the postprocessing before rendering, like so:
let mut fontdb = fontdb::Database::new();
fontdb.load_system_fonts();
let mut rtree = usvg::Tree::from_str(&svg_data, &opt).unwrap();
let steps = usvg::PostProcessingSteps {
convert_text_into_paths: true,
};
rtree.postprocess(steps, &fontdb);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With