wasm-webp 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,16 @@
1
1
  # webp.wasm
2
2
 
3
- webp.wasm is a pure Webassembly / Javascript port of libwebp.
3
+ webp.wasm is a pure Webassembly / Javascript port of libwebp. The library supports encoding animated WebP.
4
4
 
5
5
  ![CI](https://github.com/nieyuyao/webp-wasm/workflows/CI/badge.svg)
6
+ ![latest tag](https://badgen.net/github/release/nieyuyao/webp-wasm)
7
+ ![npm](https://img.shields.io/npm/v/wasm-webp.svg)
8
+
9
+ ## Install
10
+
11
+ ```shell
12
+ npm i wasm-webp
13
+ ```
6
14
 
7
15
  ## APIs
8
16
 
@@ -72,21 +80,21 @@ const webpData = await encodeRGBA(imgData.data, canvas.width, canvas.height)
72
80
  ...
73
81
  ```
74
82
 
75
- #### encode
83
+ #### encode
76
84
 
77
85
  A more advanced API is based on the WebPConfig. <b>Only the lossless and quality parameters are supported now !!!</b>. You can generate low-quality webp with this function.
78
86
 
79
87
  `function encodeRGBA(data: Uint8Array, width: number, height: number, hasAlpha: boolean,config: Partial<WebPConfig>): Promise<Nullable<Uint8Array>>`
80
88
 
81
- - hasAlpha: boolean
89
+ - hasAlpha: `boolean`
82
90
 
83
91
  Whether to include alpha chanel.
84
92
 
85
- - WebPConfig.lossless: number
93
+ - WebPConfig.lossless: `number`
86
94
 
87
95
  Lossless encoding (0=lossy(default), 1=lossless).
88
96
 
89
- - WebPConfig.quality: number
97
+ - WebPConfig.quality: `number`
90
98
 
91
99
  Between 0 and 100. Default value is 100.
92
100
 
@@ -107,20 +115,24 @@ Returns animated WebP like `GIF`.
107
115
 
108
116
  `function encodeAnimation(width: number, height: number, hasAlpha: boolean, frames: WebPAnimationFrame[]): Promise<Nullable<Uint8Array>>`
109
117
 
110
- - hasAlpha: boolean
118
+ - hasAlpha: `boolean`
111
119
 
112
120
  Whether to include alpha chanel.
113
121
 
114
122
  The WebPAnimationFrame has follow properties:
115
123
 
116
- - WebPAnimationFrame.data: Uint8Array
124
+ - WebPAnimationFrame.data: `Uint8Array`
117
125
 
118
126
  Frame bitmap.
119
127
 
120
- - WebPAnimationFrame.duration: number
128
+ - WebPAnimationFrame.duration: `number`
121
129
 
122
130
  Duration of frame.
123
131
 
132
+ - WebPAnimationFrame.config: `WebPConfig` (optional)
133
+
134
+ Per-frame encoding configuration. If not provided, default config is used (lossless: 0, quality: 100).
135
+
124
136
  ##### Example
125
137
 
126
138
  ```javascript
@@ -130,6 +142,12 @@ frames.push({
130
142
  data: ctx.getImageData(0, 0, 100, 100).data,
131
143
  duration: 20
132
144
  })
145
+ // with per-frame config
146
+ frames.push({
147
+ data: ctx.getImageData(0, 0, 100, 100).data,
148
+ duration: 20,
149
+ config: { lossless: 0, quality: 80 }
150
+ })
133
151
  const webpData = await encodeAnimation(100, 100, true, frames)
134
152
  ...
135
153
  // download webp
@@ -174,7 +192,7 @@ fr.onload = () => {
174
192
  canvas.style.height = `${result.height}px`
175
193
  canvas.width = result.width
176
194
  canvas.height = result.height
177
- ctx.putImageData(result, 0, 0)
195
+ ctx.putImageData(new ImageData(new Uint8ClampedArray(result.data)), 0, 0)
178
196
  }
179
197
  // read webp file
180
198
  fr.readAsArrayBuffer(file)
@@ -206,28 +224,73 @@ fr.readAsArrayBuffer(file)
206
224
  ...
207
225
  ```
208
226
 
227
+ #### decodeAnimation
228
+
229
+ Decoding animated WebP image. Returns an array of frames.
230
+
231
+ `function decodeAnimation(data: Uint8Array, hasAlpha: boolean): Promise<Nullable<DecodedWebPAnimationFrame[]>>`
232
+
233
+ ##### Example
234
+
235
+ ```javascript
236
+ ...
237
+ const fr = new FileReader()
238
+ fr.onload = () => {
239
+ if (!fr.result) {
240
+ return
241
+ }
242
+ webpData = fr.result as Uint8Array
243
+ const result = await decodeRGBA(webpData)
244
+ // draw imageData
245
+ ...
246
+ }
247
+ // webp file
248
+ fr.readAsArrayBuffer(file)
249
+ ...
250
+ ```
251
+
252
+ #### DecodedWebPAnimationFrame
253
+
254
+ The object have the following properties:
255
+
256
+ - DecodedWebPAnimationFrame.width: `number`
257
+
258
+ The frame image width.
259
+
260
+ - DecodedWebPAnimationFrame.height: `number`
261
+
262
+ The frame image height.
263
+
264
+ - DecodedWebPAnimationFrame.duration: `number`
265
+
266
+ The frame display duration.
267
+
268
+ - DecodedWebPAnimationFrame.data: `Uint8Array`
269
+
270
+ Raw data in pixels.
271
+
209
272
  #### WebPDecodedImageData
210
273
 
211
274
  The object have the following properties:
212
275
 
213
- - WebPDecodedImageData.width: number
276
+ - WebPDecodedImageData.width: `number`
214
277
 
215
278
  The image width in pixels.
216
279
 
217
- - WebPDecodedImageData.height: number
280
+ - WebPDecodedImageData.height: `number`
218
281
 
219
282
  The image height in pixels.
220
283
 
221
- - WebPDecodedImageData.data: Uint8Array
284
+ - WebPDecodedImageData.data: `Uint8Array`
222
285
 
223
286
  Raw data in pixels.
224
287
 
225
- > Note: It looks like an `ImageData` object, but it is not. There is actually no `ImageData` in node.
288
+ > Note: It has same properties as browser `ImageData` object, but it is not. There is actually no `ImageData` in node.
226
289
 
227
290
  ## Playing Examples
228
291
 
229
292
  ```shell
230
- npm run dev
293
+ npm run build-wasm:dev && npm run dev
231
294
  ```
232
295
 
233
296
  ## Building
package/dist/cjs/index.js CHANGED
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.decodeRGBA = exports.decodeRGB = exports.decoderVersion = exports.encodeAnimation = exports.encode = exports.encodeRGBA = exports.encodeRGB = exports.encoderVersion = void 0;
15
+ exports.decodeAnimation = exports.decodeRGBA = exports.decodeRGB = exports.decoderVersion = exports.encodeAnimation = exports.encode = exports.encodeRGBA = exports.encodeRGB = exports.encoderVersion = void 0;
16
16
  // @ts-ignore
17
17
  const webp_wasm_1 = __importDefault(require("./webp-wasm"));
18
18
  // default webp config
@@ -47,19 +47,20 @@ const encode = (data, width, height, hasAlpha, config) => __awaiter(void 0, void
47
47
  exports.encode = encode;
48
48
  const encodeAnimation = (width, height, hasAlpha, frames) => __awaiter(void 0, void 0, void 0, function* () {
49
49
  const module = yield (0, webp_wasm_1.default)();
50
- const durations = [];
51
- const dataLength = frames.reduce((acc, frame) => {
52
- acc += frame.data.length;
53
- return acc;
54
- }, 0);
55
- const data = new Uint8Array(dataLength);
56
- let offset = 0;
57
- frames.forEach(frame => {
58
- data.set(frame.data, offset);
59
- offset += frame.data.length;
60
- durations.push(frame.duration);
50
+ const frameVector = new module.VectorWebPAnimationFrame();
51
+ frames.forEach((frame) => {
52
+ const hasConfig = frame.config !== undefined;
53
+ const config = Object.assign(Object.assign({}, defaultWebpConfig), frame.config);
54
+ config.lossless = Math.min(1, Math.max(0, config.lossless));
55
+ config.quality = Math.min(100, Math.max(0, config.quality));
56
+ frameVector.push_back({
57
+ duration: frame.duration,
58
+ data: frame.data,
59
+ config,
60
+ has_config: hasConfig,
61
+ });
61
62
  });
62
- return module.encodeAnimation(width, height, hasAlpha, durations, data);
63
+ return module.encodeAnimation(width, height, hasAlpha, frameVector);
63
64
  });
64
65
  exports.encodeAnimation = encodeAnimation;
65
66
  const decoderVersion = () => __awaiter(void 0, void 0, void 0, function* () {
@@ -82,3 +83,8 @@ exports.decodeRGBA = decodeRGBA;
82
83
  // const module = await Module()
83
84
  // return module.decode(data, hasAlpha)
84
85
  // }
86
+ const decodeAnimation = (data, hasAlpha) => __awaiter(void 0, void 0, void 0, function* () {
87
+ const module = yield (0, webp_wasm_1.default)();
88
+ return module.decodeAnimation(data, hasAlpha);
89
+ });
90
+ exports.decodeAnimation = decodeAnimation;