Skip to content

Commit

Permalink
Merge pull request #13 from yisibl/add-alpha-background
Browse files Browse the repository at this point in the history
feat: `background` option supports alpha channel
  • Loading branch information
yisibl authored Oct 19, 2021
2 parents c3d6dd9 + 78bf043 commit 8310c4c
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 33 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ This changelog also contains important changes in dependencies.

## [Unreleased]

### Added

- feat: `background` option supports alpha channel, currently only supports [CSS Colors 3](https://www.w3.org/TR/css-color-3/#colorunits).
CSS color parse depends on [svgtypes](https://github.com/RazrFalcon/svgtypes/commit/266ee2caff9bd6a75d9a63b6e9850554f6de87b4).

```js
render(svgString, {
// Support
background: 'rgba(77, 25, 230, .8)',
background: 'rgb(77, 25, 230, .8)',
background: 'rgba(77%, 25%, 230%, .8)',
background: 'hsla(255, 80%, 50%, .8)',
background: 'hsl(255, 80%, 50%, .8)',
// Not support
background: 'rgb(77 25 230 / 80%)',
background: 'rgb(77 25 230 / .8)',
background: 'hsl(255deg 80% 50% / 80%)',
})
```

## [1.0.3] - 2021-10-15

### Added
Expand Down
55 changes: 34 additions & 21 deletions __test__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import { promises } from 'fs'
import { promises as fs } from 'fs'
import { join } from 'path'

import test from 'ava'
import probeImageSize from 'probe-image-size'
import jimp from 'jimp'

import { render } from '../index'

test('transparent background', async (t) => {
const filePath = './tiger.svg'
const svg = await promises.readFile(join(__dirname, filePath))
const svgString = svg.toString('utf-8')
const pngData = render(svgString)
const result = probeImageSize.sync(pngData)

t.is(result.width, 900)
t.is(result.height, 900)
})

test('fit to width', async (t) => {
const filePath = '../example/text.svg'
const svg = await promises.readFile(join(__dirname, filePath))
const svg = await fs.readFile(join(__dirname, filePath))
const svgString = svg.toString('utf-8')
const pngData = render(svgString, {
background: '#eeebe6',
Expand All @@ -28,15 +17,39 @@ test('fit to width', async (t) => {
value: 1200,
},
})
const result = probeImageSize.sync(pngData)
const result = await jimp.read(pngData)

t.is(result.getWidth(), 1200)
t.is(result.getHeight(), 623)
})

test('Set the background with alpha by rgba().', async (t) => {
const filePath = './tiger.svg'
const svg = await fs.readFile(join(__dirname, filePath))
const svgString = svg.toString('utf-8')
const pngData = render(svgString, {
background: 'rgba(0, 0, 0, 0.6)',
})
const result = await jimp.read(pngData)

t.is(result.hasAlpha(), true)
})

test('Set the background without alpha by hsla()', async (t) => {
const filePath = './tiger.svg'
const svg = await fs.readFile(join(__dirname, filePath))
const svgString = svg.toString('utf-8')
const pngData = render(svgString, {
background: 'hsla(255, 80%, 50%, 1)',
})
const result = await jimp.read(pngData)

t.is(result.width, 1200)
t.is(result.height, 623)
t.is(result.hasAlpha(), false)
})

test('Load custom font', async (t) => {
const filePath = '../example/text.svg'
const svg = await promises.readFile(join(__dirname, filePath))
const svg = await fs.readFile(join(__dirname, filePath))
const svgString = svg.toString('utf-8')
const pngData = render(svgString, {
font: {
Expand All @@ -45,8 +58,8 @@ test('Load custom font', async (t) => {
defaultFontFamily: 'Source Han Serif CN Light',
},
})
const result = probeImageSize.sync(pngData)
const result = await jimp.read(pngData)

t.is(result.width, 1324)
t.is(result.height, 687)
t.is(result.getWidth(), 1324)
t.is(result.getHeight(), 687)
})
8 changes: 4 additions & 4 deletions example/index.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
const { promises } = require('fs')
const fs = require('fs').promises
const { join } = require('path')
const { performance } = require('perf_hooks')

const { render } = require('../index')

async function main() {
const svg = await promises.readFile(join(__dirname, './text.svg'))
const svg = await fs.readFile(join(__dirname, './text.svg'))
const svgString = svg.toString('utf-8')
const t0 = performance.now()
const pngData = render(svgString, {
background: '#eeebe6',
background: 'rgba(238, 235, 230, .9)',
fitTo: {
mode: 'width',
value: 1200,
Expand All @@ -27,7 +27,7 @@ async function main() {
// eslint-disable-next-line no-console
console.log('✨ Done in', t1 - t0, 'ms')

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

main()
Binary file modified example/text-out.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 1 addition & 2 deletions example/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ export type ResvgRenderOptions = {
| 0 // optimizeQuality
| 1 // optimizeSpeed
fitTo?:
| { mode: 'width'; value: number }
| { mode: 'original' }
| { mode: 'width'; value: number }
| { mode: 'height'; value: number }
| { mode: 'zoom'; value: number }
background?: string
background?: string // Support CSS3 color, e.g. rgba(255, 255, 255, .8)
crop?: {
left: number
top: number
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-sonarjs": "^0.10.0",
"husky": "^7.0.2",
"jimp": "^0.16.1",
"lint-staged": "^11.2.0",
"npm-run-all": "^4.1.5",
"prettier": "^2.4.1",
"probe-image-size": "^7.2.1",
"typescript": "^4.4.3"
},
"dependencies": {
Expand Down Expand Up @@ -106,6 +106,7 @@
"extensions": [
"ts"
],
"timeout": "3m",
"environmentVariables": {
"TS_NODE_PROJECT": "./tsconfig.json"
}
Expand Down
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ extern crate napi;
extern crate napi_derive;

use std::convert::TryInto;
use tiny_skia::Color;
use tiny_skia::Pixmap;

/// Trys to parse an `Option<String>` into an `Option<usvg::Color>`
fn parse_color(value: &Option<String>) -> Result<Option<usvg::Color>, svgtypes::Error> {
Expand Down Expand Up @@ -66,14 +68,14 @@ fn render(ctx: napi::CallContext) -> napi::Result<napi::JsBuffer> {
.ok_or_else(|| napi::Error::from_reason("target size is zero".to_string()))?;

// Unwrap is safe, because `size` is already valid.
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
let mut pixmap = Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();

if let Some(background) = background {
pixmap.fill(tiny_skia::Color::from_rgba8(
pixmap.fill(Color::from_rgba8(
background.red,
background.green,
background.blue,
255,
background.alpha,
));
}

Expand Down

0 comments on commit 8310c4c

Please sign in to comment.