A high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.
MPL-2.0 License
Bot releases are visible (Hide)
Published by github-actions[bot] 7 months ago
Published by github-actions[bot] 7 months ago
This version solves the problem of missing DLLs caused by not installing Visual C++ Redistributable on Windows.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.6.0...v2.6.1
Published by github-actions[bot] 7 months ago
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.6.0...v2.6.1-beta.0
Published by github-actions[bot] almost 1 year ago
🚀 Up to 115x faster for very large SVG files
Now resvg has been upgraded from v0.29.0 to v0.34.0, bringing with it a host of new SVG features and performance improvements.
Support SVG2 mask-type
property.
Allows quadratic Bézier curves: text might render slightly differently (better?). This is because TrueType fonts contain only quadratic curves and we were converting them to cubic before.
Clipping and masking is up to 20% faster.
Reduces the peak memory usage for SVGs with large paths (in terms of the number of segments).
A new rendering algorithm.
When rendering isolated groups,
aka layers, we have to know the layer bounding box beforehand, which is ridiculously hard in SVG.
Previously, resvg would simply use the canvas size for all the layers.
This means that to render a 10x10px layer on a 1000x1000px canvas, we would have to allocate and then blend
a 1000x1000px layer, which is just a waste of CPU cycles.
The new rendering algorithm is able to calculate layer bounding boxes, which dramatically improves
performance when rendering a lot of tiny layers on a large canvas.
Moreover, it makes performance more linear with a canvas size increase.
The paris-30k.svg
sample from google/forma is rendered 115 times faster on M1 Pro now.
From ~33760ms down to ~290ms. 5269x3593px canvas.
If we restrict the canvas to 1000x1000px, which would contain only the actual paris-30k.svg
content,
then we're 13 times faster. From ~3252ms down to ~253ms.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.5.0...v2.6.0
Published by github-actions[bot] about 1 year ago
Now we can finally loading custom fonts in Wasm, including the WOFF2 format (see playground), thanks to the high-performance woff2-rs
.
In addition, we implemented smarter default font family fallback. the defaultFontFamily
option can now be omitted. We'll read the font-family from the incoming fonts and set it to the default.
<script src="https://unpkg.com/@resvg/resvg-wasm"></script>
<script>
(async function () {
await resvg.initWasm(fetch('https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm'))
const font = await fetch('./fonts/Pacifico-Regular.woff2')
if (!font.ok) return
const fontData = await font.arrayBuffer()
const buffer = new Uint8Array(fontData)
const opts = {
font: {
fontBuffers: [buffer], // New in 2.5.0, loading custom fonts.
// defaultFontFamily: 'Pacifico', // You can omit this.
},
}
const svg = '<svg> ... </svg>' // Input SVG, String or Uint8Array
const resvgJS = new resvg.Resvg(svg, opts)
const pngData = resvgJS.render(svg, opts) // Output PNG data, Uint8Array
const pngBuffer = pngData.asPng()
const svgURL = URL.createObjectURL(new Blob([pngData], { type: 'image/png' }))
document.getElementById('output').src = svgURL
})()
</script>
fontBuffers
option. Thanks to @antmelnyk #217
We have improved the upstream svgtypes#14, allow parsing of float rgb()/rgba()
values from CSS Color 4 draft like rgb(3.14, 110, 201)
.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.4.1...v2.5.0
Published by github-actions[bot] over 1 year ago
defaultFontFamily
not working by @yisibl in https://github.com/yisibl/resvg-js/pull/208
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.4.0...v2.4.1
Published by github-actions[bot] over 1 year ago
This is a brand new version with 2-3x faster performance. It also resolves an issue with a specific SVG causing an error, and all users are advised to upgrade to this version.
resvg-js(Rust):
39.6 ops/s, ±1.72% | fastest
sharp:
10.9 ops/s, ±31.43% | 72.47% slower
svg2img(canvg + node-canvas):
10.8 ops/s, ±28.52% | slowest, 72.73% slower
The upgrade will be hard due to the big changes made to upstream resvg. resvg 0.28.0 started with the removal of the ability to output SVG string, and we had to backport that functionality to a new crate: usvg-writer
.
Eventually, we upgraded resvg for 2 successive versions, and are now at the latest 0.29.0.
fix: 'the previous segment must be M/L/C' error. #204 Thanks to @yisibl
This is a normal error thrown by resvg when parsing Path Command, and has been confirmed as fixed in resvg 0.29.0.
Add a test to ensure it is now fixed.
thread '<unnamed>' panicked at 'the previous segment must be M/L/C'
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: failed to initiate panic, error 5
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.3.1...v2.4.0
Published by github-actions[bot] over 1 year ago
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.3.0...v2.3.1
Published by github-actions[bot] over 1 year ago
fix: update napi-rs(2.10.13) to resolve Electron 21+ create Buffer issues. #195
Electron 21 and later will have the V8 Memory Cage enabled, with implications for some native modules.
https://www.electronjs.org/blog/v8-memory-cage
This means that all napi-rs-based native modules will be affected. Usually there is an error like this:
UnhandledPromiseRejectionWarning: Error: Failed to create napi buffer
Good thing napi-rs has implemented a compatible approach in the new version, thanks to @Brooooooklyn's work.
feat: add wasm file to exports. Thanks to @hadeeb #186
This solves the problem that direct require.resolve("@resvg/resvg-wasm/index_bg.wasm")
in tools like vite or webpack would report an error.
Module not found: Package path ./index_bg.wasm is not exported from package
/playground/node_modules/@resvg/resvg-wasm (see exports field in
/playground/node_modules/@resvg/resvg-wasm/package.json)
See the Node.js documentation for details about why:
Existing packages introducing the "exports" field will prevent consumers of the package from using any entry points that are not defined
fix(ci): use zig to cross-compile armv7. #176
This solves the problem of CI errors:
Error: /lib/arm-linux-gnueabihf/libm.so.6: version `GLIBC_2.35' not found (required by /build/resvgjs.linux-arm-gnueabihf.node)
Due to the GitHub Actions Ubuntu upgrade from 20.04 to 22.04, the glibc version became 2.35. To maintain our compatibility, zig cross-compilation is now enabled to support older versions of glibc systems.
Distribution | Glibc | GCC |
---|---|---|
CentOS 7 | 2.17 | 4.8.5 |
Ubuntu 16.04 | 2.23 | 5.4.0 |
Ubuntu 18.04 | 2.27 | 7.5.0 |
Ubuntu 20.04 | 2.31 | 9.4.0 |
Ubuntu 22.04 | 2.35 | 11.2.0 |
Debian 10.12 | 2.28 | 8.3.0 |
Debian 11.4 | 2.31 | 10.2.1 |
doc: add Node.js 18 to 'Support matrix'. #155
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.2.0...v2.3.0
Published by github-actions[bot] almost 2 years ago
Now resvg-js can be run natively (not Wasm) directly in Deno, this allows to get close to the performance of Node.js native addons in Deno.
deno run --unstable --allow-read --allow-write --allow-ffi example/index-deno.js
See Deno Example
import * as path from 'https://deno.land/[email protected]/path/mod.ts'
import { Resvg } from 'npm:@resvg/resvg-js'
const __dirname = path.dirname(path.fromFileUrl(import.meta.url))
const svg = await Deno.readFile(path.join(__dirname, './text.svg'))
const resvg = new Resvg(svg, opts)
const pngData = resvg.render()
const pngBuffer = pngData.asPng()
await Deno.writeFile(path.join(__dirname, './text-out-deno.png'), pngBuffer)
In addition, resvg-js can return the raw pixels data of the PNG, which can be very convenient for scenes where only pixels need to be processed.
.pixels()
API for returning PNG pixels data (#123).paint-order
attribute support. Markers can only be under or above the shape.writing-mode
variants vertical-rl
and vertical-lr
. Thanks to @yisibl.dpi
option is not the DPI in the PNG file. (#146)infer
crate, this can reduce the size of Wasm files.png
crate in renovate.json
. (by @CGQAQ in #161)Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.1.0...v2.2.0
Published by github-actions[bot] over 2 years ago
Add imagesToResolve()
and resolveImage()
APIs to load image URL. By @zimond in #102
xlink:href
starting with http://
or https://
.In order to support loading image URL, we forked the rust side of resvg and made some improvements.
Now please witness the magic moment:
Add innerBBox()
API. By @yisibl in #105
Calculate a maximum bounding box of all visible elements in this SVG. (Note: path bounding box are approx values).
Add getBBox()
API. By @yisibl in #108
We designed it to correspond to the SVGGraphicsElement.getBBox()
method in the browser.
This is different from the innerBBox()
API, by default it does apply transform calculations and gets the BBox with curves exactly. This works well in most use cases, the only drawback is that it does not calculate BBoxes with stroke correctly.
Add cropByBBox()
API. By @yisibl in #108
With this API, we can crop the generated bitmap based on the BBox(bounding box).
const fs = require('fs')
const { Resvg } = require('@resvg/resvg-js')
const svg = '' // some SVG string or file.
const resvg = new Resvg(svg)
const innerBBox = resvg.innerBBox()
const bbox = resvg.getBBox()
// Crop the bitmap according to bbox,
// The argument to the `.cropByBBox()` method accepts `bbox` or `innerBBox`.
if (bbox) resvg.cropByBBox(bbox)
const pngData = resvg.render()
const pngBuffer = pngData.asPng()
console.info('SVG BBox: ', `${bbox.width} x ${bbox.height}`)
fs.writeFileSync('out.png', pngBuffer)
feat: upgrade svgtypes to 0.8.1 to support 4 digits and 8 digits hex colors. By @yisibl in #127
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0...v2.1.0
Published by github-actions[bot] over 2 years ago
feat: add bbox related API by @zimond in https://github.com/yisibl/resvg-js/pull/90
This version does not yet implement Node.js or Wasm bindings, so it is not available for now.
fix: rebuild Wasm to solve the problem of not working in the browser by @yisibl in https://github.com/yisibl/resvg-js/pull/106
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0...v2.0.1
Published by github-actions[bot] over 2 years ago
Published by github-actions[bot] over 2 years ago
The resvg-js API is now largely stable.
render()
now no longer returns the Buffer
directly, you need to get the buffer via the new render().asPng()
, also added render().width
and render().height
to return the size of the PNG.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0-alpha.6...v2.0.0-beta.0
Published by github-actions[bot] over 2 years ago
chore: add libc fields on linux platform packages by @yisibl in https://github.com/yisibl/resvg-js/pull/89
On Linux, it is not possible to tell exactly what kind of C library a native modules depends on just by os/cpu, so yarn 3.2 and cnpm added libc fields to further distinguish this case. This avoids downloading both gnu
and musl
packages at the same time.
Currently only yarn 3.2+ and cnpm are supported, the npm implementation is still under discussion.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0-alpha.5...v2.0.0-alpha.6
Published by github-actions[bot] over 2 years ago
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0-alpha.4...v2.0.0-alpha.5
Published by github-actions[bot] over 2 years ago
1949570
bytes1266413
bytesFull Changelog: https://github.com/yisibl/resvg-js/compare/v1.4.0...v2.0.0-alpha.4
Published by github-actions[bot] over 2 years ago
.width
and .height
to get the original size of the SVG.toString()
to convert SVG shapes or text to path.new Resvg()
to create the constructor.const { render } = require('@resvg/resvg-js')
const svg = '' // svg buffer or string
const pngData = render(svg, opts)
const { Resvg } = require('@resvg/resvg-js')
const svg = '' // svg buffer or string
const resvg = new Resvg(svg, opts)
const pngData = resvg.render()
// New!
console.info('Simplified svg string \n', resvg.toString())
console.info('SVG original size:', `${resvg.width} x ${resvg.height}px`)
Full Changelog: https://github.com/yisibl/resvg-js/compare/v1.4.0...v2.0.0-alpha.3
Published by github-actions[bot] over 2 years ago
feat: upgrade resvg to 0.22.0
Support svg
referenced by <use>
, this is often used in svg sprite.
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg">
<rect width="50%" height="50%" fill="green" />
</svg>
<use id="use1" x="50%" y="50%" xlink:href="#svg1" />
</svg>
feat: upgrade fontdb to 0.9.0, loading system fonts will become faster.
There are many CJK fonts installed in my local OS, the test result is 2.5 times faster:
Loaded 1085 font faces in 860.447ms.
Loaded 1085 font faces in 339.665ms.
Published by github-actions[bot] over 2 years ago
feat: playground uses unpkg.com's online resources
<script src="https://unpkg.com/@resvg/[email protected]/index.min.js"></script>
feat: preload wasm in the playground
<link rel="preload" as="fetch" type="application/wasm" href="https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm" />
chore: upload wasm file to artifacts
Switching from local to building in CI (Linux-x64-gnu) for .wasm
files can reduce the file size a bit.
After gzip compression, the .wasm
file is only about 700kB.
Full Changelog: https://github.com/yisibl/resvg-js/compare/v2.0.0-alpha.0...v2.0.0-alpha.1