135 lines
No EOL
4.3 KiB
Markdown
135 lines
No EOL
4.3 KiB
Markdown
# browser-image-resizer
|
|
|
|
## Introduction
|
|
|
|
This library allows for cross-browser image downscaling utilizing `OffscreenCanvas`.
|
|
|
|
## Note
|
|
|
|
- This is browser-only utility and will not work in Node.js.
|
|
- Safari 16.4 or later is required due to the use of `OffscreenCanvas`.
|
|
https://caniuse.com/offscreencanvas
|
|
|
|
## Installation
|
|
|
|
### NPM/Yarn/pnpm
|
|
|
|
- `npm install @valkyriecoms/browser-image-resizer`
|
|
- `yarn add @valkyriecoms/browser-image-resizer`
|
|
- `pnpm add @valkyriecoms/browser-image-resizer`
|
|
|
|
## Usage
|
|
|
|
### In the main thread
|
|
|
|
```typescript
|
|
import { readAndCompressImage } from 'browser-image-resizer';
|
|
|
|
const config = {
|
|
quality: 0.7,
|
|
width: 800,
|
|
height: 600
|
|
};
|
|
|
|
// Note: A single file comes from event.target.files on <input>
|
|
async function uploadImage(file) {
|
|
try {
|
|
let resizedImage = await readAndCompressImage(file, config);
|
|
|
|
const url = `http://localhost:3001/upload`;
|
|
const formData = new FormData();
|
|
formData.append('images', resizedImage);
|
|
const options = {
|
|
method: 'POST',
|
|
body: formData
|
|
};
|
|
|
|
let result = await fetch(url, options);
|
|
|
|
// TODO: Handle the result
|
|
console.log(result);
|
|
return result;
|
|
} catch (error) {
|
|
console.error(error);
|
|
throw(error);
|
|
}
|
|
}
|
|
```
|
|
|
|
### In worker
|
|
Even large images can be processed in a separate thread using a worker.
|
|
|
|
#### worker.js
|
|
|
|
```typescript
|
|
import { readAndCompressImage } from "browser-image-resizer";
|
|
|
|
onmessage = async (e) => {
|
|
const converted = await readAndCompressImage(e.data, { maxWidth: 300 });
|
|
postMessage(converted, [converted]);
|
|
}
|
|
```
|
|
|
|
#### Main Thread
|
|
|
|
```typescript
|
|
const worker = new Worker('worker.js');
|
|
|
|
const img = document.getElementById('viewer_img');
|
|
worker.onmessage = (e) => {
|
|
img.src = URL.createObjectURL(e.data);
|
|
};
|
|
|
|
async function convert(file: File) {
|
|
const bmp = await createImageBitmap(file);
|
|
worker.postMessage(bmp, [bmp]);
|
|
}
|
|
```
|
|
|
|
## API
|
|
|
|
### `readAndCompressImage(file, config) => Promise<Blob | OffscreenCanvas>`
|
|
|
|
#### Inputs
|
|
|
|
* `file`: An image source that createImageBitmap can read.
|
|
See https://developer.mozilla.org/en-US/docs/Web/API/createImageBitmap
|
|
* `config`: See below
|
|
|
|
| Property Name | Purpose | Default Value |
|
|
| ------------- |-------------| -----:|
|
|
| `argorithm` | Algorithm used for downscaling (see below) | 'null' |
|
|
| `processByHalf` | Whether to process downscaling by `drawImage(source, 0, 0, source.width / 2, source.height / 2)` until the size is smaller than twice the target size. | true |
|
|
| `quality` | The quality of jpeg (or webp) | 0.5 |
|
|
| `maxWidth` | The maximum width for the downscaled image | 800 |
|
|
| `maxHeight` | The maximum height for the downscaled image | 600 |
|
|
| `debug` | console.log image update operations | false |
|
|
| `mimeType` | specify image output type other than jpeg / If set `null`, function returns OffscreenCanvas | 'image/jpeg' |
|
|
|
|
##### `argorithm`
|
|
|
|
* `null`: Just resize with `drawImage()`. The best quality and fastest.
|
|
* `bilinear`: Better quality, slower. Comes from upstream (ericnogralesbrowser-image-resizer).
|
|
* `hermite`: Worse quality, faster. Comes from [viliusle/Hermite-resize](https://github.com/viliusle/Hermite-resize). Will dispatch workers for better performance.
|
|
* `hermite_single`: Worse quality, faster. Single-threaded.
|
|
|
|
#### Outputs
|
|
|
|
A Promise that yields an Image Blob or OffscreenCanvas
|
|
|
|
### `calculateSize(src, config)`
|
|
`calculateSize(src: { width: number; height: number; }, config) => { width: number; height: number; }`
|
|
|
|
With this function you can get the pre-calculated width and height of the resulting image.
|
|
|
|
### Output Image Specification
|
|
The output image is derived from `OffscreenCanvas.convertToBlob`.
|
|
https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/convertToBlob
|
|
|
|
- EXIF and other metadata will be erased.
|
|
- Rotation will be automatically corrected.
|
|
* It is based on the specifications of recent versions of modern browsers and may not work with older browsers.
|
|
* See https://github.com/w3c/csswg-drafts/issues/4666#issuecomment-610962845
|
|
* Firefox support seems to be available from version 78.
|
|
- Color profile is srgb. Firefox 97 does not attach the ICC profile, but Chrome does.
|
|
- You can specify image/webp as the mimeType but [Safari does not support.](https://developer.apple.com/documentation/webkitjs/htmlcanvaselement/1630000-todataurl). |