pica 9.0.1 → 10.0.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.
Files changed (40) hide show
  1. package/README.md +95 -52
  2. package/dist/pica.cjs.d.ts +69 -0
  3. package/dist/pica.es.d.ts +66 -0
  4. package/dist/pica.js +1711 -2527
  5. package/dist/pica.js.map +1 -0
  6. package/dist/pica.min.js +2 -7
  7. package/dist/pica.min.js.map +1 -0
  8. package/dist/pica.min.mjs +8 -0
  9. package/dist/pica.min.mjs.map +1 -0
  10. package/dist/pica.mjs +1729 -0
  11. package/dist/pica.mjs.map +1 -0
  12. package/dist/pica_main.js +1720 -0
  13. package/dist/pica_main.js.map +1 -0
  14. package/dist/pica_main.mjs +1714 -0
  15. package/dist/pica_main.mjs.map +1 -0
  16. package/dist/pica_worker.js +1074 -0
  17. package/dist/pica_worker.js.map +1 -0
  18. package/package.json +51 -24
  19. package/index.js +0 -729
  20. package/lib/mathlib.js +0 -57
  21. package/lib/mm_resize/convolve.c +0 -256
  22. package/lib/mm_resize/convolve.js +0 -263
  23. package/lib/mm_resize/convolve.wasm +0 -0
  24. package/lib/mm_resize/convolve_wasm_base64.js +0 -5
  25. package/lib/mm_resize/index.js +0 -8
  26. package/lib/mm_resize/resize.js +0 -52
  27. package/lib/mm_resize/resize_filter_gen.js +0 -120
  28. package/lib/mm_resize/resize_filter_info.js +0 -70
  29. package/lib/mm_resize/resize_wasm.js +0 -113
  30. package/lib/mm_unsharp_mask/index.js +0 -8
  31. package/lib/mm_unsharp_mask/unsharp_mask.c +0 -218
  32. package/lib/mm_unsharp_mask/unsharp_mask.js +0 -89
  33. package/lib/mm_unsharp_mask/unsharp_mask.wasm +0 -0
  34. package/lib/mm_unsharp_mask/unsharp_mask_wasm.js +0 -55
  35. package/lib/mm_unsharp_mask/unsharp_mask_wasm_base64.js +0 -5
  36. package/lib/pool.js +0 -65
  37. package/lib/stepper.js +0 -61
  38. package/lib/tiler.js +0 -95
  39. package/lib/utils.js +0 -204
  40. package/lib/worker.js +0 -49
package/README.md CHANGED
@@ -14,22 +14,34 @@ pica - high quality image resize in browser
14
14
  With pica you can:
15
15
 
16
16
  - Reduce upload size for large images, saving upload time.
17
- - Saves server resources on image processing.
17
+ - Save server resources on image processing.
18
18
  - Generate thumbnails in browser.
19
19
  - ...
20
20
 
21
- **Note. If you need File/Blob resize (from form's file input), consider use
21
+ **Note. If you need File/Blob resize (from form's file input), consider using
22
22
  [image-blob-reduce](https://github.com/nodeca/image-blob-reduce).** It has
23
23
  additional machinery to process orientation, keep EXIF metadata and so on.
24
24
 
25
25
 
26
- Migration from pica v6 to pica v7
27
- ---------------------------------
26
+ Migration from pica v9 to pica v10
27
+ ----------------------------------
28
28
 
29
- Multiply `unsharpAmount` by 2, divide `unsharpThreshold` by 2, example:
30
-
31
- - `pica@6`: `pica.resize(a, b, { unsharpAmount: 80, unsharpThreshold: 2 })`
32
- - `pica@7`: `pica.resize(a, b, { unsharpAmount: 160, unsharpThreshold: 1 })`
29
+ - If you targeted IE or other legacy browsers — drop them, only modern
30
+ browsers are supported now.
31
+ - If you used `new` on the default export (`new (require('pica'))()` or
32
+ `import Pica from 'pica'; new Pica()`) switch to either the factory call
33
+ `require('pica')()` / `pica()`, or to the named `Pica` class:
34
+ `import { Pica } from 'pica'; new Pica()`. The default export is now a
35
+ factory function only.
36
+ - If you passed `createCanvas` in options — remove it. To override canvas
37
+ creation, expose a custom `OffscreenCanvas` on the global scope instead.
38
+ - If you used the positional `quality` argument
39
+ (`pica.resize(from, to, 3)`) — switch to
40
+ `pica.resize(from, to, { filter: 'lanczos3' })`. The object form
41
+ `{ quality: 3 }` also works but is deprecated, prefer `filter`.
42
+ - If you relied on multiple `Pica` instances sharing the same worker pool —
43
+ refactor to create a single instance and reuse it. Implicit sharing is
44
+ gone.
33
45
 
34
46
 
35
47
  Prior to use
@@ -40,15 +52,15 @@ Here is a short list of problems you can face:
40
52
  - Loading image:
41
53
  - Due to JS security restrictions, you can process images
42
54
  from the same domain or local files only. If you load images from
43
- remote domain use proper `Access-Control-Allow-Origin` header.
44
- - iOS has a memory limits for canvas elements, that may cause
55
+ a remote domain, use the proper `Access-Control-Allow-Origin` header.
56
+ - iOS has memory limits for canvas elements, which may cause
45
57
  problems in some cases, [more details](https://github.com/nodeca/pica/wiki/iOS-Memory-Limit).
46
- - If your source data is jpeg image, it can be rotated. Consider use
58
+ - If your source data is a jpeg image, it can be rotated. Consider using
47
59
  [image-blob-reduce](https://github.com/nodeca/image-blob-reduce).
48
60
  - Saving image:
49
- - Some ancient browsers do not support `canvas.toBlob()` method.
50
- Use `pica.toBlob()`, it includes required shim.
51
- - For jpeg source, it's a good idea to keep `exif` data. Consider use
61
+ - Some ancient browsers do not support the `canvas.toBlob()` method.
62
+ Use `pica.toBlob()`, it includes the required shim.
63
+ - For jpeg source, it's a good idea to keep `exif` data. Consider using
52
64
  [image-blob-reduce](https://github.com/nodeca/image-blob-reduce).
53
65
  - Quality
54
66
  - JS canvas does not support access to info about gamma correction.
@@ -72,18 +84,40 @@ Use
72
84
  ---
73
85
 
74
86
  ```js
75
- const pica = require('pica')();
87
+ // ESM (default factory)
88
+ import pica from 'pica';
89
+ const resizer = pica();
90
+
91
+ // ESM (class)
92
+ import { Pica } from 'pica';
93
+ const resizer = new Pica();
94
+
95
+ // CommonJS
96
+ const resizer = require('pica')();
76
97
 
77
98
  // Resize from Canvas/Image to another Canvas
78
- pica.resize(from, to)
99
+ resizer.resize(from, to)
79
100
  .then(result => console.log('resize done!'));
80
101
 
81
102
  // Resize & convert to blob
82
- pica.resize(from, to)
83
- .then(result => pica.toBlob(result, 'image/jpeg', 0.90))
103
+ resizer.resize(from, to)
104
+ .then(result => resizer.toBlob(result, 'image/jpeg', 0.90))
84
105
  .then(blob => console.log('resized to canvas & created blob!'));
85
106
  ```
86
107
 
108
+ By default, the main entry (`pica`) inlines the webworker code. If you want
109
+ the worker as a separate file (smaller main bundle, easier CSP), use the
110
+ split build — `pica/dist/pica_main.mjs` together with
111
+ `pica/dist/pica_worker.js`. In that case `workerURL` is required:
112
+
113
+ ```js
114
+ import createPica from 'pica/dist/pica_main.mjs';
115
+
116
+ const resizer = createPica({
117
+ workerURL: new URL('pica/dist/pica_worker.js', import.meta.url)
118
+ });
119
+ ```
120
+
87
121
 
88
122
  API
89
123
  ---
@@ -96,18 +130,15 @@ Create resizer instance with given config (optional):
96
130
  to restrict peak memory use. Default 1024.
97
131
  - __features__ - list of features to use. Default is
98
132
  `[ 'js', 'wasm', 'ww' ]`. Can be `[ 'js', 'wasm', 'cib', 'ww' ]`
99
- or `[ 'all' ]`. Note, `cib` is buggy in Chrome and not supports default
100
- `mks2013` filter.
101
- - __idle__ - cache timeout, ms. Webworkers create is not fast.
102
- This option allow reuse webworkers effectively. Default 2000.
133
+ or `[ 'all' ]`. Note, `cib` is buggy in Chrome and does not support the
134
+ default `mks2013` filter.
135
+ - __idle__ - cache timeout, ms. Creating webworkers is not fast,
136
+ so this option allows reusing them effectively. Default 2000.
137
+ - __workerURL__ - URL for `pica_worker.js` when using split builds
138
+ (`pica_main.js` / `pica_main.mjs`) with `ww` enabled. Full builds
139
+ (`pica.js` / `pica.mjs`) include worker code and do not need this option.
103
140
  - __concurrency__ - max webworkers pool size. Default is autodetected
104
141
  CPU count, but not more than 4.
105
- - __createCanvas__ - function which returns a new canvas, used internally
106
- by pica.
107
- Default returns a [\<canvas\> element](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API),
108
- but this function could return an [OffscreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas)
109
- instead (to run pica in a Service Worker). Function signature: createCanvas(width: number, height: number): Canvas
110
-
111
142
 
112
143
  __Important!__ Latest browsers may support resize via [createImageBitmap](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap).
113
144
  This feature is supported (`cib`) but disabled by default and not recommended
@@ -115,9 +146,9 @@ for use. So:
115
146
 
116
147
  - `createImageBitmap()` is used for non-blocking image decode (when available,
117
148
  without downscale).
118
- - It's resize feature is blocked by default pica config. Enable it only on your
119
- own risk. Result with enabled `cib` will depend on your browser. Result
120
- without `cib` will be predictable and good.
149
+ - Its resize feature is blocked in the default pica config. Enable it only at
150
+ your own risk. The result with `cib` enabled will depend on your browser.
151
+ The result without `cib` will be predictable and good.
121
152
 
122
153
 
123
154
  ### .resize(from, to, options) -> Promise
@@ -127,9 +158,9 @@ taken from source and destination objects.
127
158
 
128
159
  - __from__ - source, can be `Canvas`, `Image` or `ImageBitmap`.
129
160
  - __to__ - destination canvas, its size is supposed to be non-zero.
130
- - __options__ - quality (number) or object:
161
+ - __options__ - object:
131
162
  - __quality__ (deprecated, use `.filter` instead) - 0..3.
132
- - __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.js](https://github.com/nodeca/pica/blob/master/lib/mm_resize/resize_filter_info.js) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
163
+ - __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.ts](https://github.com/nodeca/pica/blob/master/src/mm_resize/resize_filter_info.ts) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
133
164
  - __unsharpAmount__ - >=0. Default = `0` (off). Usually
134
165
  value between 100 to 200 is good. Note, `mks2013` filter already does
135
166
  optimal sharpening.
@@ -145,7 +176,8 @@ Result is Promise, resolved with `to` on success.
145
176
 
146
177
  __(!)__ If you need to process multiple images, do it
147
178
  sequentially to optimize CPU & memory use. Pica already knows
148
- how to use multiple cores (if browser allows).
179
+ how to use multiple cores (if browser allows). Create a single
180
+ `Pica` instance and reuse it across calls.
149
181
 
150
182
 
151
183
  ### .toBlob(canvas, mimeType [, quality]) -> Promise
@@ -169,7 +201,7 @@ binary data (for example, if you decode jpeg files "manually").
169
201
  - __toWidth__ - output width, >=0, in pixels.
170
202
  - __toHeight__ - output height, >=0, in pixels.
171
203
  - __quality__ (deprecated, use `.filter` instead) - 0..3.
172
- - __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.js](https://github.com/nodeca/pica/blob/master/lib/mm_resize/resize_filter_info.js) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
204
+ - __filter__ - filter name (Default - `mks2013`). See [resize_filter_info.ts](https://github.com/nodeca/pica/blob/master/src/mm_resize/resize_filter_info.ts) for details. `mks2013` does both resize and sharpening, it's optimal and not recommended to change.
173
205
  - __unsharpAmount__ - >=0. Default = `0` (off). Usually
174
206
  value between 100 to 200 is good. Note, `mks2013` filter already does
175
207
  optimal sharpening.
@@ -179,34 +211,34 @@ binary data (for example, if you decode jpeg files "manually").
179
211
  - __unsharpThreshold__ - 0..255. Default = `0`. Threshold
180
212
  for applying unsharp mask.
181
213
  - __dest__ - Optional. Output buffer to write data,
182
- if you don't wish `pica` to create new one.
214
+ if you don't wish `pica` to create a new one.
183
215
 
184
216
  Result is Promise, resolved with resized rgba buffer.
185
217
 
186
218
 
187
219
  ### What is "quality"
188
220
 
189
- Pica has presets to adjust speed/quality ratio.
190
- Simply use `quality` option param:
221
+ `quality` is a legacy preset still accepted for backwards compatibility,
222
+ but deprecated — prefer the `filter` option. Mapping:
191
223
 
192
- - 0 - Box filter, window 0.5px
193
- - 1 - Hamming filter, window 1.0px
194
- - 2 - Lanczos filter, window 2.0px
195
- - 3 - Lanczos filter, window 3.0px
224
+ - 0 - Box filter, window 0.5px (`filter: 'box'`)
225
+ - 1 - Hamming filter, window 1.0px (`filter: 'hamming'`)
226
+ - 2 - Lanczos filter, window 2.0px (`filter: 'lanczos2'`)
227
+ - 3 - Lanczos filter, window 3.0px (`filter: 'lanczos3'`)
196
228
 
197
- In real world you will never need to change default (max)
198
- quality. All this variations were implemented to better
229
+ In the real world you will never need to change the default (`mks2013`)
230
+ filter. All these variations were implemented to better
199
231
  understand resize math :)
200
232
 
201
233
 
202
234
  ### Unsharp mask
203
235
 
204
- After scale down image can look a bit blured. It's good idea to sharpen it
205
- a bit. Pica has built-in "unsharp mask" filter (off by default).
206
- Set `unsharpAmount` to positive number to activate the filter.
236
+ After scale down, an image can look a bit blurred. It's a good idea to
237
+ sharpen it a bit. Pica has a built-in "unsharp mask" filter (off by default).
238
+ Set `unsharpAmount` to a positive number to activate the filter.
207
239
 
208
- Filter's parameters are similar to ones from Photoshop.
209
- We recommend to start with `unsharpAmount = 160`,
240
+ Filter parameters are similar to ones from Photoshop.
241
+ We recommend starting with `unsharpAmount = 160`,
210
242
  `unsharpRadius = 0.6` and `unsharpThreshold = 1`.
211
243
  There is [a correspondence between UnsharpMask parameters
212
244
  in popular graphics software](https://github.com/nodeca/pica/wiki/Unsharp-mask-params-in-popular-softare).
@@ -227,9 +259,20 @@ We didn't have time to test all possible combinations, but in general:
227
259
  - If you plan to use only pure math core,
228
260
  then [typed arrays support](http://caniuse.com/#feat=typedarrays) will be enough.
229
261
 
230
- __Note.__ Though you can run this package on `node.js`, browsers
231
- are the main target platform. On server side we recommend to use
232
- [sharp](https://github.com/lovell/sharp).
262
+ __Note.__ Browsers are the main target platform. For Node.js we strongly
263
+ recommend [sharp](https://github.com/lovell/sharp) it is faster and
264
+ produces better quality. If you really need pica in Node.js anyway, it can
265
+ run in a limited mode (no WebWorkers) by exposing an external canvas library
266
+ as the global `OffscreenCanvas`. This is not recommended.
267
+
268
+ ```js
269
+ import { Canvas } from '@napi-rs/canvas'; // or any other canvas library
270
+ import pica from 'pica';
271
+
272
+ global.OffscreenCanvas = Canvas;
273
+
274
+ const resizer = pica(); // WebWorkers will not be used
275
+ ```
233
276
 
234
277
 
235
278
  References
@@ -0,0 +1,69 @@
1
+ type MathResizeFilter = 'box' | 'hamming' | 'lanczos2' | 'lanczos3' | 'mks2013';
2
+
3
+ type PicaFeaturesFlat = ('js' | 'wasm' | 'ww' | 'cib' | 'all')[];
4
+ type Filter = MathResizeFilter;
5
+ type CibResizeQuality = 0 | 1 | 2 | 3;
6
+ type PicaCanvas = HTMLCanvasElement | OffscreenCanvas;
7
+ type PicaSource = PicaCanvas | HTMLImageElement | ImageBitmap;
8
+ type CreateCanvasPreference = {
9
+ preferOffscreen?: boolean;
10
+ };
11
+ interface PicaOptions {
12
+ tile?: number;
13
+ concurrency?: number;
14
+ features?: PicaFeaturesFlat;
15
+ idle?: number;
16
+ workerURL?: string | URL;
17
+ }
18
+ interface _ResizeOptionsCommon {
19
+ quality?: CibResizeQuality;
20
+ filter?: Filter;
21
+ unsharpAmount?: number;
22
+ unsharpRadius?: number;
23
+ unsharpThreshold?: number;
24
+ }
25
+ interface ResizeOptions extends _ResizeOptionsCommon {
26
+ cancelToken?: Promise<unknown>;
27
+ }
28
+ interface ResizeBufferOptions extends _ResizeOptionsCommon {
29
+ src: Uint8Array | Uint8ClampedArray;
30
+ width: number;
31
+ height: number;
32
+ toWidth: number;
33
+ toHeight: number;
34
+ dest?: Uint8Array;
35
+ }
36
+
37
+ declare class Pica {
38
+ private options;
39
+ private __limit;
40
+ private resize_features;
41
+ private __workersPool;
42
+ private capabilities;
43
+ private __requested_features;
44
+ private __mathlib;
45
+ private __initPromise?;
46
+ constructor(options?: PicaOptions);
47
+ init(): Promise<this>;
48
+ private __init;
49
+ createCanvas(width: number, height: number, preferOffscreen?: CreateCanvasPreference): PicaCanvas;
50
+ private __createWorkerSlot;
51
+ private __invokeWorker;
52
+ private __invokeResize;
53
+ private __extractTileData;
54
+ private __landTileData;
55
+ private __tileAndResize;
56
+ private __planStagesAndResize;
57
+ private __resizeViaCreateImageBitmap;
58
+ resize<TCanvas extends PicaCanvas>(from: PicaSource, to: TCanvas, options?: ResizeOptions): Promise<TCanvas>;
59
+ resizeBuffer(options: ResizeBufferOptions): Promise<Uint8Array>;
60
+ toBlob(canvas: HTMLCanvasElement | OffscreenCanvas, mimeType?: string, quality?: number): Promise<Blob>;
61
+ debug(..._args: unknown[]): void;
62
+ }
63
+ declare function pica(options?: PicaOptions): Pica;
64
+
65
+ declare const picaWithClass: typeof pica & {
66
+ Pica: typeof Pica;
67
+ };
68
+
69
+ export { picaWithClass as default };
@@ -0,0 +1,66 @@
1
+ type MathResizeFilter = 'box' | 'hamming' | 'lanczos2' | 'lanczos3' | 'mks2013';
2
+
3
+ type PicaFeaturesFlat = ('js' | 'wasm' | 'ww' | 'cib' | 'all')[];
4
+ type Filter = MathResizeFilter;
5
+ type CibResizeQuality = 0 | 1 | 2 | 3;
6
+ type PicaCanvas = HTMLCanvasElement | OffscreenCanvas;
7
+ type PicaSource = PicaCanvas | HTMLImageElement | ImageBitmap;
8
+ type CreateCanvasPreference = {
9
+ preferOffscreen?: boolean;
10
+ };
11
+ interface PicaOptions {
12
+ tile?: number;
13
+ concurrency?: number;
14
+ features?: PicaFeaturesFlat;
15
+ idle?: number;
16
+ workerURL?: string | URL;
17
+ }
18
+ interface _ResizeOptionsCommon {
19
+ quality?: CibResizeQuality;
20
+ filter?: Filter;
21
+ unsharpAmount?: number;
22
+ unsharpRadius?: number;
23
+ unsharpThreshold?: number;
24
+ }
25
+ interface ResizeOptions extends _ResizeOptionsCommon {
26
+ cancelToken?: Promise<unknown>;
27
+ }
28
+ interface ResizeBufferOptions extends _ResizeOptionsCommon {
29
+ src: Uint8Array | Uint8ClampedArray;
30
+ width: number;
31
+ height: number;
32
+ toWidth: number;
33
+ toHeight: number;
34
+ dest?: Uint8Array;
35
+ }
36
+
37
+ declare class Pica {
38
+ private options;
39
+ private __limit;
40
+ private resize_features;
41
+ private __workersPool;
42
+ private capabilities;
43
+ private __requested_features;
44
+ private __mathlib;
45
+ private __initPromise?;
46
+ constructor(options?: PicaOptions);
47
+ init(): Promise<this>;
48
+ private __init;
49
+ createCanvas(width: number, height: number, preferOffscreen?: CreateCanvasPreference): PicaCanvas;
50
+ private __createWorkerSlot;
51
+ private __invokeWorker;
52
+ private __invokeResize;
53
+ private __extractTileData;
54
+ private __landTileData;
55
+ private __tileAndResize;
56
+ private __planStagesAndResize;
57
+ private __resizeViaCreateImageBitmap;
58
+ resize<TCanvas extends PicaCanvas>(from: PicaSource, to: TCanvas, options?: ResizeOptions): Promise<TCanvas>;
59
+ resizeBuffer(options: ResizeBufferOptions): Promise<Uint8Array>;
60
+ toBlob(canvas: HTMLCanvasElement | OffscreenCanvas, mimeType?: string, quality?: number): Promise<Blob>;
61
+ debug(..._args: unknown[]): void;
62
+ }
63
+ declare function pica(options?: PicaOptions): Pica;
64
+
65
+ export { Pica, pica as default };
66
+ export type { CibResizeQuality, Filter, PicaCanvas, PicaFeaturesFlat, PicaOptions, PicaSource, ResizeBufferOptions, ResizeOptions };