Resize images in browser without pixelation and reasonably fast. Autoselect the best of available technologies: webworkers, webassembly, createImageBitmap, pure JS.
With pica you can:
Note. If you need File/Blob resize (from form's file input), consider using image-blob-reduce. It has additional machinery to process orientation, keep EXIF metadata and so on.
new on the default export (new (require('pica'))() or
import Pica from 'pica'; new Pica()) — switch to either the factory call
require('pica')() / pica(), or to the named Pica class:
import { Pica } from 'pica'; new Pica(). The default export is now a
factory function only.createCanvas in options — remove it. To override canvas
creation, expose a custom OffscreenCanvas on the global scope instead.quality argument
(pica.resize(from, to, 3)) — switch to
pica.resize(from, to, { filter: 'lanczos3' }). The object form
{ quality: 3 } also works but is deprecated, prefer filter.Pica instances sharing the same worker pool —
refactor to create a single instance and reuse it. Implicit sharing is
gone.Here is a short list of problems you can face:
Access-Control-Allow-Origin header.canvas.toBlob() method.
Use pica.toBlob(), it includes the required shim.exif data. Consider using
image-blob-reduce.npm install pica
// ESM (default factory)
import pica from 'pica';
const resizer = pica();
// ESM (class)
import { Pica } from 'pica';
const resizer = new Pica();
// CommonJS
const resizer = require('pica')();
// Resize from Canvas/Image to another Canvas
resizer.resize(from, to)
.then(result => console.log('resize done!'));
// Resize & convert to blob
resizer.resize(from, to)
.then(result => resizer.toBlob(result, 'image/jpeg', 0.90))
.then(blob => console.log('resized to canvas & created blob!'));
By default, the main entry (pica) inlines the webworker code. If you want
the worker as a separate file (smaller main bundle, easier CSP), use the
split build — pica/dist/pica_main.mjs together with
pica/dist/pica_worker.js. In that case workerURL is required:
import createPica from 'pica/dist/pica_main.mjs';
const resizer = createPica({
workerURL: new URL('pica/dist/pica_worker.js', import.meta.url)
});
[!NOTE] For a quick look at
dist/folder contents, see https://unpkg.com/pica@latest/.
Create resizer instance with given config (optional):
[ 'js', 'wasm', 'ww' ]. Can be [ 'js', 'wasm', 'cib', 'ww' ]
or [ 'all' ]. Note, cib is buggy in Chrome and does not support the
default mks2013 filter.pica_worker.js when using split builds
(pica_main.js / pica_main.mjs) with ww enabled. Full builds
(pica.js / pica.mjs) include worker code and do not need this option.Important! Latest browsers may support resize via createImageBitmap.
This feature is supported (cib) but disabled by default and not recommended
for use. So:
createImageBitmap() is used for non-blocking image decode (when available,
without downscale).cib enabled will depend on your browser.
The result without cib will be predictable and good.Resize image from one canvas (or image) to another. Sizes are taken from source and destination objects.
Canvas, Image or ImageBitmap..filter instead) - 0..3.mks2013). See resize_filter_info.ts for details. mks2013 does both resize and sharpening, it's optimal and not recommended to change.0 (off). Usually
value between 100 to 200 is good. Note, mks2013 filter already does
optimal sharpening.0. Threshold for
applying unsharp mask.Result is Promise, resolved with to on success.
(!) If you need to process multiple images, do it
sequentially to optimize CPU & memory use. Pica already knows
how to use multiple cores (if browser allows). Create a single
Pica instance and reuse it across calls.
Convenience method, similar to canvas.toBlob(), but with
promise interface & polyfill for old browsers.
Supplementary method, not recommended for direct use. Resize Uint8Array with raw RGBA bitmap (don't confuse with jpeg / png / ... binaries). It does not use tiles & webworkers. Left for special cases when you really need to process raw binary data (for example, if you decode jpeg files "manually").
.filter instead) - 0..3.mks2013). See resize_filter_info.ts for details. mks2013 does both resize and sharpening, it's optimal and not recommended to change.0 (off). Usually
value between 100 to 200 is good. Note, mks2013 filter already does
optimal sharpening.0. Threshold
for applying unsharp mask.pica to create a new one.Result is Promise, resolved with resized rgba buffer.
quality is a legacy preset still accepted for backwards compatibility,
but deprecated — prefer the filter option. Mapping:
filter: 'box')filter: 'hamming')filter: 'lanczos2')filter: 'lanczos3')In the real world you will never need to change the default (mks2013)
filter. All these variations were implemented to better
understand resize math :)
After scale down, an image can look a bit blurred. It's a good idea to
sharpen it a bit. Pica has a built-in "unsharp mask" filter (off by default).
Set unsharpAmount to a positive number to activate the filter.
Filter parameters are similar to ones from Photoshop.
We recommend starting with unsharpAmount = 160,
unsharpRadius = 0.6 and unsharpThreshold = 1.
There is a correspondence between UnsharpMask parameters
in popular graphics software.
We didn't have time to test all possible combinations, but in general:
Note. Browsers are the main target platform. For Node.js we strongly
recommend sharp — it is faster and
produces better quality. If you really need pica in Node.js anyway, it can
run in a limited mode (no WebWorkers) by exposing an external canvas library
as the global OffscreenCanvas. This is not recommended.
import { Canvas } from '@napi-rs/canvas'; // or any other canvas library
import pica from 'pica';
global.OffscreenCanvas = Canvas;
const resizer = pica(); // WebWorkers will not be used
You can find these links useful:
Available as part of the Tidelift Subscription.
The maintainers of pica and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. Learn more.