Skip to content

Commit

Permalink
doc: perf readme
Browse files Browse the repository at this point in the history
  • Loading branch information
nieyuyao committed Apr 9, 2024
1 parent d3c144a commit 008c9d0
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI
name: CI

on:
push:
Expand Down
210 changes: 207 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,218 @@
# WIP

# `webp.wasm`

A webp wasm library based on libwebp.
webp.wasm is a pure Webassembly / Javascript port of libwebp.

![CI](https://github.com/nieyuyao/webp-wasm/workflows/CI/badge.svg)

## APIs

### Encode

#### encode

Get encoder encoderVersion.

`function encoderVersion(): Promise<string>`

##### Example

```javascript
const version = await encoderVersion()
console.log(version) // 1.3.2
```

#### encodeRGB

Encodes rgb bitmap an outputs webp.

`function encodeRGB(rgb: Uint8ClampedArray, width: number, height: number, quality?: number): Promise<Nullable<Uint8ClampedArray>>`

##### Example

```javascript
...
const ctx = canvas.getContext('2d')!
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const buf = new Uint8ClampedArray(3 * canvas.width, canvas.height)
let j = 0
// remove alpha
imgData.data.forEach((pixel, i) => {
if ((i + 1) % 4 === 0) {
return
}
buf[j] = pixel
j++
})
const result = await encodeRGB(buf, canvas.width, canvas.height)
const blob = new Blob([result!], {type: 'image/webp'})
const blobURL = URL.createObjectURL(blob);
// download webp
const a = document.createElement('a')
a.download = '1.webp'
a.href = blobURL
document.body.appendChild(a)
a.click()
a.remove()
```

#### encodeRGBA

Encodes rgba bitmap an outputs webp.

`function encodeRGBA(rgba: Uint8ClampedArray, width: number, height: number, quality?: number): Promise<Nullable<Uint8ClampedArray>>`

##### Example

```javascript
...
const ctx = canvas.getContext('2d')!
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const result = await encodeRGBA(imgData.data, canvas.width, canvas.height)
// download webp
...
```

#### encode

A more advanced API is based on the WebPConfig. <b>Only the lossless and quality parameters are supported now !!!</b>.

`function encodeRGBA(data: Uint8ClampedArray, width: number, height: number, hasAlpha: boolean,config: Partial<WebPConfig>): Promise<Nullable<Uint8ClampedArray>>`

- hasAlpha: boolean

Whether to include alpha chanel.

- WebPConfig.lossless: number

Lossless encoding (0=lossy(default), 1=lossless).

- WebPConfig.quality: number

Between 0 and 100.

##### Example

```javascript
...
const ctx = canvas.getContext('2d')!
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
const result = await encode(imgData.data, canvas.width, canvas.height, true, { lossless: 0 })
// download webp
...
```

#### encodeAnimation

Encodes frame data an outputs animated webp.

`function encodeAnimation(width: number, height: number, hasAlpha: boolean, frames: WebPAnimationFrame[]): Promise<Nullable<Uint8ClampedArray>>`

- hasAlpha: boolean

Whether to include alpha chanel.

- WebPAnimationFrame.data: Uint8ClampedArray

Frame data.

- WebPAnimationFrame.duration: number

Duration of frame.

##### Example

```javascript
...
// record each frame
frames.push({
data: ctx.getImageData(0, 0, 100, 100).data,
duration: 20
})
const result = await encodeAnimation(100, 100, true, frames)
...
// download webp
```

### Decode

#### decoderVersion

Get decoder version.

`function decoderVersion(): Promise<string>`

##### Example

```javascript
const version = await decoderVersion()
console.log(version) // 1.3.2
```

#### decodeRGB

Decodes webp and outputs `ImageData` contains rgb bitmap.

`function decodeRGB(rgb: Uint8ClampedArray): Promise<Nullable<ImageData>>`

##### Example

```javascript
...
const fr = new FileReader()
fr.onload = () => {
if (!fr.result) {
return
}
webpData = fr.result as Uint8ClampedArray
const result = await decodeRGB(webpData)
// draw imageData
const ctx = canvas.getContext('2d')!
ctx.clearRect(0, 0, canvas.width, canvas.height)
canvas.style.width = `${result.width}px`
canvas.style.height = `${result.height}px`
canvas.width = result.width
canvas.height = result.height
ctx.putImageData(result, 0, 0)
}
// read webp file
fr.readAsArrayBuffer(file)
...
```

#### decodeRGBA

Decodes webp and outputs `ImageData` contains rgba bitmap.

`function decodeRGB(rgb: Uint8ClampedArray): Promise<Nullable<ImageData>>`

##### Example

```javascript
...
const fr = new FileReader()
fr.onload = () => {
if (!fr.result) {
return
}
webpData = fr.result as Uint8ClampedArray
const result = await decodeRGBA(webpData)
// draw imageData
...
}
// webp file
fr.readAsArrayBuffer(file)
...
```

#### Example
## Playing Examples

```shell
npm run dev
```

#### Building
## Building

```shell
npm run build
Expand Down
4 changes: 3 additions & 1 deletion example/Decode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ const onChange = (event) => {
}
isUploaded = true
const file = files[0]
console.log(file)
const fr = new FileReader()
fr.onload = () => {
if (!fr.result) {
Expand All @@ -33,6 +32,9 @@ const drawWebp = async () => {
return
}
const result = await decodeRGBA(webpData)
if (!result) {
return
}
const ctx = canvas.getContext('2d')!
ctx.clearRect(0, 0, canvas.width, canvas.height)
canvas.style.width = `${result.width}px`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "webp-wasm",
"name": "webp.wasm",
"version": "0.0.1",
"description": "",
"main": "dist/cjs/index.js",
Expand Down
4 changes: 2 additions & 2 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ export declare const encodeRGB: (
rgb: Uint8ClampedArray,
width: number,
height: number,
quality: number
quality?: number
) => Promise<Nullable<Uint8ClampedArray>>
export declare const encodeRGBA: (
rgba: Uint8ClampedArray,
width: number,
height: number,
quality: number
quality?: number
) => Promise<Nullable<Uint8ClampedArray>>
export declare const encode: (
data: Uint8ClampedArray,
Expand Down
8 changes: 5 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const encodeRGB = async (
quality?: number
): Promise<Nullable<Uint8ClampedArray>> => {
const module = await Module()
quality = typeof quality !== 'number' ? 100 : Math.min(Math.max(0, quality))
quality = typeof quality !== 'number' ? 100 : Math.min(100, Math.max(0, quality))
return module.encodeRGB(rgb, width, height, quality)
}

Expand All @@ -29,10 +29,10 @@ export const encodeRGBA = async (
rgba: Uint8ClampedArray,
width: number,
height: number,
quality: number
quality?: number
): Promise<Nullable<Uint8ClampedArray>> => {
const module = await Module()
quality = typeof quality !== 'number' ? 100 : Math.min(Math.max(0, quality))
quality = typeof quality !== 'number' ? 100 : Math.min(100, Math.max(0, quality))
return module.encodeRGBA(rgba, width, height, quality)
}

Expand All @@ -49,6 +49,8 @@ export const encode = async (
...defaultWebpConfig,
...config,
}
webpConfig.lossless = Math.min(1, Math.max(0, webpConfig.lossless))
webpConfig.quality = Math.min(100, Math.max(0, webpConfig.quality))
return module.encode(data, width, height, hasAlpha, webpConfig)
}

Expand Down
2 changes: 1 addition & 1 deletion tests/encode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('encode', () => {
const source = ctx.getImageData(0, 0, img.width, img.height)
const buf = Buffer.alloc(3 * img.width * img.height)
let j = 0
// no alpha
// remove alpha
source.data.forEach((pixel, i) => {
if ((i + 1) % 4 === 0) {
return
Expand Down

0 comments on commit 008c9d0

Please sign in to comment.