Save SVG element with custom font as an image

It is easy to convert an SVG element into an image. Serialize the SVG element into a Base64 string and set the image src attribute.

const serializer = new XMLSerializer();
const svgString = serializer.serializeToString(svgElem);
const img = new Image();
img.src = 'data:image/svg+xml;base64,' + Base64.encode(svgString);

It is easy to save the image to a file. We do this using the Canvas toBlob and window saveAs API.

img.onload = () => {
    const context = canvas.getContext('2d');
    context.drawImage(img, 0, 0);
    canvas.toBlob(blob => {
        saveAs(blob, fileName);
    });
};

Custom Fonts in SVG

But there is a problem. When the SVG uses custom fonts, the image does not have appropriate fonts.

SVG Image with custom Font
Saved PNG Image

The saved PNG image has a default fallback font. And the text is visibly blurred.

There is a way to fix this problem. Use Font Squirrel to create a Base64 version of the font and embed the font into the SVG element.

Upload the font to Font Squirrel, Select Expert Option and in CSS option, select Base 64 encoding.

Expert option in Font Squirrel
Select Base64 Encode option

In the stylesheet.css file of the downloads, the Base64 string is available.

Place the custom font within a style tag. And place the style tag within a defs element. Append the defs element to the SVG element.

const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
const style = document.createElementNS("http://www.w3.org/2000/svg", "style");
style.type = "text/css";
// prettier-ignore
style.innerHTML = `
                    @font-face {
                        font-family: 'Axiforma';
                        src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAH3EABIAAAABFSgAAQAAYa/yp) format('woff');
                    }
                    `;
defs.appendChild(style);
svgElem.appendChild(defs);

With this code in place, the image saved from SVG element has the appropriate fonts.

About fonts

As an aside, there are a few things to learn about fonts in a web page. Usually, modern web browsers download fonts in WOFF2 format. Almost all browsers except IE accept the WOFF format (which is more like the version 1). WOFF is also known as web fonts. Older IE browsers like OpenType fonts (OTF/EOT). And there are TrueType fonts (TTF) and SVG fonts.

Each font type is optimised for a specific scenario. Google Web Fonts have fonts stored in 30 different formats. Depending on the request (browser and OS), it returns the right font. When you are making inline fonts (for this code) , choose the WOFF format as it has the maximum support.

@font-face {
    font-family: 'Axiforma';
    src: url('../fonts/kastelov-axiforma-regular-webfont.woff2') format('woff2'),
        url('../fonts/kastelov-axiforma-regular-webfont.woff') format('woff'),
        url('../fonts/kastelov-axiforma-regular.otf') format('opentype');
}

Usually, we specify multiple font formats in the stylesheet and let the browser decide what to pick.

Related Posts

Leave a Reply

Your email address will not be published.