Reputation: 2923
I would like to convert an SVG to a PNG inside a Web Worker. My problem is, that the DOM is not accessible from within the Worker, so I cannot draw the SVG to a canvas or something like that.
Upvotes: 9
Views: 1736
Reputation: 31698
Chrome does not intend to support the creation of ImageBitmap
in service workers starting from an SVG blob: https://issues.chromium.org/issues/41250699
If you need to do this in a Web Extension, you can use the chrome.offscreen
API and use the DOM as you normally would on a web page.
Upvotes: 0
Reputation: 73
You can use thumbo
import Thumbo, { Transfer } from "thumbo";
Thumbo.init().then(async () => {
Thumbo.thumbnail(
Transfer(await (await fetch("/path/to/img.svg")).arrayBuffer()),
Thumbo.ImageFormat.Svg,
20,
20
).then((thumbnailBuffer) => {
document.getElementById("img1").src = URL.createObjectURL(
new Blob([thumbnailBuffer])
);
});
Thumbo.thumbnailFromUrl(
"https://example.com/image.svg",
Thumbo.ImageFormat.Svg,
20,
20
).then((thumbnailBuffer) => {
document.getElementById("img2").src = URL.createObjectURL(
new Blob([thumbnailBuffer])
);
});
});
Under the hood, thumbo uses Rust's tiny_skia & resvg libraries compiled to a Web Assembly module, to render SVG in a web worker and convert it to PNG. See thumbo-core, thumbo
PS: I'm the author of thumbo
Upvotes: 2
Reputation:
Weeell, you can always manually parse the SVG and build a bitmap from that, but (!) it's a tad more work obviously as you'd have to build a SVG parser as well as a PNG writer, not to mention rasterizing code for lines and two-modes polygon fill incl. anti-aliasing, pattern, matrix, composition, blending and gradient support. Could be a nice weekend project though :)
On a more serious note though: you can only do this with the built-in tools using regular context (none-webworker) or optionally set up a server based service.
Upvotes: 2