1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
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<Abs>) {
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
}
|