use base64::Engine; use ecow::{eco_format, EcoString}; use typst::layout::{Abs, Axes}; use typst::visualize::{Image, ImageFormat, RasterFormat, VectorFormat}; use crate::SVGRenderer; impl SVGRenderer { /// Render an image element. pub(super) fn render_image(&mut self, image: &Image, size: &Axes) { let url = convert_image_to_base64_url(image); self.xml.start_element("image"); self.xml.write_attribute("xlink:href", &url); self.xml.write_attribute("width", &size.x.to_pt()); self.xml.write_attribute("height", &size.y.to_pt()); self.xml.write_attribute("preserveAspectRatio", "none"); self.xml.end_element(); } } /// Encode an image into a data URL. The format of the URL is /// `data:image/{format};base64,`. #[comemo::memoize] pub fn convert_image_to_base64_url(image: &Image) -> EcoString { let format = match image.format() { ImageFormat::Raster(f) => match f { RasterFormat::Png => "png", RasterFormat::Jpg => "jpeg", RasterFormat::Gif => "gif", }, ImageFormat::Vector(f) => match f { VectorFormat::Svg => "svg+xml", }, }; let mut url = eco_format!("data:image/{format};base64,"); let data = base64::engine::general_purpose::STANDARD.encode(image.data()); url.push_str(&data); url }