Skip to content

Commit

Permalink
feat: switch to the rust-based resvg-js
Browse files Browse the repository at this point in the history
https://github.com/yisibl/resvg-js

canvg and node-canvas are no longer needed.
  • Loading branch information
yisibl authored and fuzhenn committed Apr 17, 2022
1 parent de91247 commit 78aaa22
Show file tree
Hide file tree
Showing 12 changed files with 1,433 additions and 1,845 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.DS_Store
node_modules
.vscode/
130 changes: 81 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,135 @@
# node-svg2img

[![CircleCI](https://circleci.com/gh/fuzhenn/node-svg2img.svg?style=svg)](https://circleci.com/gh/fuzhenn/node-svg2img)
<a href="https://www.npmjs.com/package/svg2img"><img src="https://img.shields.io/npm/v/svg2img.svg?sanitize=true" alt="npm version"></a>

A high-performance in-memory convertor to convert svg to png/jpeg images for Node.
Based on [canvg](https://github.com/gabelerner/canvg) and [node-canvas](https://github.com/Automattic/node-canvas)
A high-performance in-memory convertor to convert SVG to png/jpeg images for Node.js.

Please notice: this library is only for Node, can not run in browsers.
Starting with v1.0, we switched to [resvg-js](https://github.com/yisibl/resvg-js) for better performance and compatibility to render SVG.

Because of [xmldom](https://github.com/jindw/xmldom), it requires Node.js 10 or newer.

(If your node version is lower, you can `npm i [email protected]` instead which only required node 4)
> Please notice: this library is only for Node.js, can not run in browsers.
> (If your Node.js version is lower, you can `npm i [email protected]` instead which only required Node.js v4)
## Install

```bash
npm i svg2img
npm i svg2img@next
```

## Usage
### Conversion

To output JPEG image, you should install `node-canvas` with jpeg support.

```javascript
var fs = require('fs');
var svg2img = require('svg2img');
var btoa = require('btoa');

var svgString = [
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="236" height="120" ',
'viewBox="0 0 236 120">',
'<rect x="14" y="23" width="200" height="50" fill="#55FF55" stroke="black" stroke-width="1" />',
'</svg>'
].join('');

//1. convert from svg string
const fs = require('fs');
const svg2img = require('svg2img');
const btoa = require('btoa');

const svgString = `<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="236" height="120" viewBox="0 0 236 120"><rect x="14" y="23" width="200" height="50" fill="#55FF55" stroke="black" stroke-width="1" /></svg>`;

//1. Convert from svg string
svg2img(svgString, function(error, buffer) {
//returns a Buffer
fs.writeFileSync('foo1.png', buffer);
});

//2. convert from svg's base64 string
//2. Convert from svg's base64 string
svg2img(
'data:image/svg+xml;base64,'+ btoa(svgString),
'data:image/svg+xml;base64,' + btoa(svgString),
function(error, buffer) {
fs.writeFileSync('foo2.png', buffer);
});

fs.writeFileSync('foo.svg', new Buffer(svgString));

//3. convert from a local file
svg2img(__dirname+'/foo.svg', function(error, buffer) {
//3. Convert from a local file
svg2img(__dirname + '/foo.svg', function(error, buffer) {
fs.writeFileSync('foo3.png', buffer);
});

//4. convert from a remote file
//4. Convert from a remote file
svg2img(
'https://upload.wikimedia.org/wikipedia/commons/a/a0/Svg_example1.svg',
function(error, buffer) {
fs.writeFileSync('foo4.png', buffer);
});

//5. convert to jpeg file
svg2img(svgString, {format:'jpg','quality':75}, function(error, buffer) {
//5. Convert to jpeg file
svg2img(svgString, { format: 'jpg', 'quality': 75 }, function(error, buffer) {
//default jpeg quality is 75
fs.writeFileSync('foo5.jpg', buffer);
});
```

### Scale
You can scale the svg by giving width and height.

You can scale the svg by giving width or height, svg2img Always maintain aspect ratio.

```javascript
svg2img(__dirname+'/foo.svg', {'width':800, 'height':600} ,function(error, buffer) {
svg2img(__dirname + '/foo.svg', {
resvg: {
fitTo: {
mode: 'width', // or height
value: 600,
},
}
} ,function(error, buffer) {
fs.writeFileSync('foo.png', buffer);
});
```

By default, the aspect ratio isn't preserved when scaling (same as `preserveAspectRatio="none"`). You can change it using `preserveAspectRatio` option. It can be `true` to keep original value or any other value to replace with.
```javascript
// use original preserveAspectRatio
svg2img(
__dirname+'/foo.svg',
{width:800, height:600, preserveAspectRatio:true},
function(error, buffer) {
fs.writeFileSync('foo.png', buffer);
}
);

// use custom preserveAspectRatio
svg2img(
__dirname+'/foo.svg',
{width:800, height:600, preserveAspectRatio:'xMinYMid meet'},
function(error, buffer) {
fs.writeFileSync('foo.png', buffer);
}
);
### More options

resvg-js supports [more features](https://github.com/yisibl/resvg-js#features), such as Loading fonts, setting `background`, `crop`, etc.

In svg2img, you can configure it with the `resvg` option.

```js
export type ResvgRenderOptions = {
font?: {
loadSystemFonts?: boolean
fontFiles?: string[]
fontDirs?: string[]
defaultFontFamily?: string
defaultFontSize?: number
serifFamily?: string
sansSerifFamily?: string
cursiveFamily?: string
fantasyFamily?: string
monospaceFamily?: string
}
dpi?: number
languages?: string[]
shapeRendering?:
| 0 // optimizeSpeed
| 1 // crispEdges
| 2 // geometricPrecision
textRendering?:
| 0 // optimizeSpeed
| 1 // optimizeLegibility
| 2 // geometricPrecision'
imageRendering?:
| 0 // optimizeQuality
| 1 // optimizeSpeed
fitTo?:
| { mode: 'original' }
| { mode: 'width'; value: number }
| { mode: 'height'; value: number }
| { mode: 'zoom'; value: number }
background?: string // Support CSS3 color, e.g. rgba(255, 255, 255, .8)
crop?: {
left: number
top: number
right?: number
bottom?: number
}
logLevel?: 'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
}
```


## Run the Test

```bash
npm i
npm test
```
18 changes: 18 additions & 0 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const fs = require('fs');
const { join } = require('path');
const svg2img = require('../index');

// Base64 or remote URLs are also supported.
const svgFile = join(__dirname, '../test/tiger.svg');

svg2img(svgFile, {
resvg: {
fitTo: {
mode: 'width',
value: 900,
},
background: 'skyblue',
}
}, function (error, buffer) {
fs.writeFileSync(__dirname + '/index.png', buffer);
});
Binary file added example/index.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/write-jpg.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions example/write-jpg.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require('fs');
const { join } = require('path')
const svg2img = require('../index');

const svgFile = join(__dirname, '../test/tiger.svg')
svg2img(svgFile, {
format: 'jpg',
quality: 50,
resvg: {
fitTo: {
mode: 'height',
value: 600,
},
}
}, function (error, buffer) {
fs.writeFileSync(__dirname + '/write-jpg.jpg', buffer);
});
49 changes: 44 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,53 @@ declare enum Format {
}

export interface svg2imgOptions {
width?: number;
height?: number;
preserveAspectRatio?: boolean | string;
resvg?: ResvgRenderOptions;
format?: Format;
quality?: number;
compressionLevel?: number;
}

declare function svg2img(svg: string, options: svg2imgOptions, callback: Callback): void;
// See https://github.com/yisibl/resvg-js/blob/main/index.d.ts
export type ResvgRenderOptions = {
font?: {
loadSystemFonts?: boolean
fontFiles?: string[]
fontDirs?: string[]
defaultFontFamily?: string
defaultFontSize?: number
serifFamily?: string
sansSerifFamily?: string
cursiveFamily?: string
fantasyFamily?: string
monospaceFamily?: string
}
dpi?: number
languages?: string[]
shapeRendering?:
| 0 // optimizeSpeed
| 1 // crispEdges
| 2 // geometricPrecision
textRendering?:
| 0 // optimizeSpeed
| 1 // optimizeLegibility
| 2 // geometricPrecision'
imageRendering?:
| 0 // optimizeQuality
| 1 // optimizeSpeed
fitTo?:
| { mode: 'original' }
| { mode: 'width'; value: number }
| { mode: 'height'; value: number }
| { mode: 'zoom'; value: number }
background?: string // Support CSS3 color, e.g. rgba(255, 255, 255, .8)
crop?: {
left: number
top: number
right?: number
bottom?: number
}
logLevel?: 'off' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
}

declare function svg2img(svg: string, options?: svg2imgOptions, callback: Callback): void;
declare function svg2img(svg: string, callback: Callback): void;
export default svg2img;
Loading

0 comments on commit 78aaa22

Please sign in to comment.