Skip to content
forked from yisibl/resvg-js

A high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.

License

Notifications You must be signed in to change notification settings

shuding/resvg-js

Β 
Β 

Repository files navigation

resvg-js

GitHub CI Status @resvg/resvg-js npm version @resvg/resvg-js downloads

resvg-js is a high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.

Features

  • Fast, safe and zero dependencies.
  • Convert SVG to PNG, includes cropping, scaling and setting the background color.
  • Support system fonts and custom fonts in SVG text.
  • v2: Gets the width and height of the SVG and the generated PNG.
  • v2: Support for outputting simplified SVG strings, such as converting shapes(rect, circle, etc) to <path>.
  • v2: Support WebAssembly.
  • v2: Support to get SVG bounding box and crop according to bounding box.
  • v2: Support for loading images of external links in <image>.
  • No need for node-gyp and postinstall, the .node file has been compiled for you.
  • Cross-platform support, including Apple M Chips.

Installation

Node.js

npm i @resvg/resvg-js

Browser(Wasm)

<script src="https://unpkg.com/@resvg/resvg-wasm"></script>

This example will load Source Han Serif, and then render the SVG to PNG.

node example/index.js

Loaded 1 font faces in 0ms.
Font './example/SourceHanSerifCN-Light-subset.ttf':0 found in 0.006ms.
✨ Done in 55.65491008758545 ms
SVG PNG
Anime girl SVG
CC BY 3.0: Niabot
Anime girl png
CC BY 3.0: Niabot

Usage

Node.js

const { promises } = require('fs')
const { join } = require('path')
const { Resvg } = require('@resvg/resvg-js')

async function main() {
  const svg = await promises.readFile(join(__dirname, './text.svg'))
  const opts = {
    background: 'rgba(238, 235, 230, .9)',
    fitTo: {
      mode: 'width',
      value: 1200,
    },
    font: {
      fontFiles: ['./example/SourceHanSerifCN-Light-subset.ttf'], // Load custom fonts.
      loadSystemFonts: false, // It will be faster to disable loading system fonts.
      defaultFontFamily: 'Source Han Serif CN Light',
    },
  }
  const resvg = new Resvg(svg, opts)
  const pngData = resvg.render()
  const pngBuffer = pngData.asPng()

  console.info('Original SVG Size:', `${resvg.width} x ${resvg.height}`)
  console.info('Output PNG Size  :', `${pngData.width} x ${pngData.height}`)

  await promises.writeFile(join(__dirname, './text-out.png'), pngBuffer)
}

main()

WebAssembly

Although we support the use of Wasm packages in Node.js, this is not recommended. The native addon performs better.

Browser

<script src="https://unpkg.com/@resvg/resvg-wasm"></script>
<script>
  (async function () {
    // The Wasm must be initialized first
    await resvg.initWasm(fetch('https://unpkg.com/@resvg/resvg-wasm/index_bg.wasm'))
    const opts = {
      fitTo: {
        mode: 'width', // If you need to change the size
        value: 800,
      },
    }

    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>

See playground, it is also possible to call Wasm in Node.js, but there is a performance penalty and this is not recommended.

Benchmark

Running "resize width" suite...
  resvg-js(Rust):
    12 ops/s, Β±22.66%   | fastest πŸš€

  sharp:
    9 ops/s, Β±64.52%    | 25% slower

  skr-canvas(Rust):
    7 ops/s, Β±3.72%    | 41.67% slower

  svg2img(canvg and node-canvas):
    6 ops/s, Β±16.94%    | slowest, 50% slower

Support matrix

node12 node14 node16 npm
Windows x64 βœ“ βœ“ βœ“ npm version
Windows x32 βœ“ βœ“ βœ“ npm version
Windows arm64 βœ“ βœ“ βœ“ npm version
macOS x64 βœ“ βœ“ βœ“ npm version
macOS arm64(M1) βœ“ βœ“ βœ“ npm version
Linux x64 gnu βœ“ βœ“ βœ“ npm version
Linux x64 musl βœ“ βœ“ βœ“ npm version
Linux arm gnu βœ“ βœ“ βœ“ npm version
Linux arm64 gnu βœ“ βœ“ βœ“ npm version
Linux arm64 musl βœ“ βœ“ βœ“ npm version
Android arm64 βœ“ βœ“ βœ“ npm version
Android armv7 βœ“ βœ“ βœ“ npm version

Test or Contributing

Build Node.js bindings

npm i
npm run build
npm test

Build WebAssembly bindings

npm i
npm run build:wasm
npm run test:wasm

Roadmap

I will consider implementing the following features, if you happen to be interested, please feel free to discuss with me or submit a PR.

  • Support async API
  • Upgrade to napi-rs v2
  • Support WebAssembly
  • Output usvg-simplified SVG string
  • Support for getting SVG Bounding box
  • Support for generating more lossless bitmap formats, e.g. avif, webp, JPEG XL

Release package

We use GitHub actions to automatically publish npm packages.

# 1.0.0 => 1.0.1
npm version patch

# or 1.0.0 => 1.1.0
npm version minor

License

MPLv2.0

Copyright (c) 2021-present, yisibl(一丝)

About

A high-performance SVG renderer and toolkit, powered by Rust based resvg and napi-rs.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 31.4%
  • JavaScript 29.2%
  • TypeScript 23.9%
  • HTML 15.5%