image_compressor_wasm
v1.0.0
Published
A fast WebAssembly image compression library for JavaScript, React, and Next.js
Maintainers
Readme
Image Compressor WASM
A fast image compression library powered by WebAssembly.
Image Compressor WASM provides a simple API for converting and compressing images into JPEG or PNG format. It can be used in JavaScript, TypeScript, React, Next.js, and supported Node.js environments.
Features
- Fast image processing powered by WebAssembly
- JPEG output support
- PNG output support
- Simple
Uint8ArrayAPI - Compatible with JavaScript and TypeScript
- Suitable for React and Next.js applications
- Can be used for client-side image compression
- Includes TypeScript declarations
Installation
Install the package using npm:
npm install image_compressor_wasmUsing pnpm:
pnpm add image_compressor_wasmUsing Yarn:
yarn add image_compressor_wasmBasic Usage
Import the compression functions from the package:
import {
compress_to_jpeg,
compress_to_png
} from 'image_compressor_wasm';
const input = new Uint8Array(imageData);
const jpegOutput = compress_to_jpeg(input);
const pngOutput = compress_to_png(input);Both functions accept a Uint8Array and return the compressed image as a new Uint8Array.
Node.js Usage
The following example reads an image, converts it to JPEG and PNG, and writes the results to the file system.
import fs from 'node:fs';
import {
compress_to_jpeg,
compress_to_png
} from 'image_compressor_wasm';
function readImage(filePath) {
const buffer = fs.readFileSync(filePath);
return new Uint8Array(buffer);
}
function saveImage(imageData, outputPath) {
const buffer = Buffer.from(imageData);
fs.writeFileSync(outputPath, buffer);
}
const input = readImage('input.jpg');
const jpegStartTime = performance.now();
const jpegOutput = compress_to_jpeg(input);
const jpegDuration = performance.now() - jpegStartTime;
saveImage(jpegOutput, 'photo.jpg');
console.log(`JPEG compression completed in ${jpegDuration.toFixed(2)} ms`);
console.log(`JPEG output size: ${jpegOutput.byteLength} bytes`);
const pngStartTime = performance.now();
const pngOutput = compress_to_png(input);
const pngDuration = performance.now() - pngStartTime;
saveImage(pngOutput, 'photo.png');
console.log(`PNG compression completed in ${pngDuration.toFixed(2)} ms`);
console.log(`PNG output size: ${pngOutput.byteLength} bytes`);Because this package is distributed as an ES module, use import instead of require.
Browser Usage
Use File.arrayBuffer() to read a selected image as a Uint8Array.
import {
compress_to_jpeg
} from 'image_compressor_wasm';
async function compressImage(file) {
const inputBuffer = await file.arrayBuffer();
const input = new Uint8Array(inputBuffer);
const output = compress_to_jpeg(input);
return new Blob([output], {
type: 'image/jpeg'
});
}Create an object URL to preview the compressed image:
const compressedBlob = await compressImage(file);
const previewUrl = URL.createObjectURL(compressedBlob);
console.log(previewUrl);
Revoke the object URL when it is no longer needed:URL.revokeObjectURL(previewUrl);React Usage
The following component allows the user to select an image, compresses it to JPEG, and displays a preview.
import { useEffect, useState } from 'react';
import {
compress_to_jpeg
} from 'image_compressor_wasm';
export default function ImageCompressor() {
const [previewUrl, setPreviewUrl] = useState('');
const [originalSize, setOriginalSize] = useState(0);
const [compressedSize, setCompressedSize] = useState(0);
const [processing, setProcessing] = useState(false);
useEffect(() => {
return () => {
if (previewUrl) {
URL.revokeObjectURL(previewUrl);
}
};
}, [previewUrl]);
async function handleFileChange(event) {
const file = event.target.files?.[0];
if (!file) {
return;
}
setProcessing(true);
try {
const inputBuffer = await file.arrayBuffer();
const input = new Uint8Array(inputBuffer);
const output = compress_to_jpeg(input);
const compressedBlob = new Blob([output], {
type: 'image/jpeg'
});
const nextPreviewUrl = URL.createObjectURL(compressedBlob);
setPreviewUrl((currentPreviewUrl) => {
if (currentPreviewUrl) {
URL.revokeObjectURL(currentPreviewUrl);
}
return nextPreviewUrl;
});
setOriginalSize(file.size);
setCompressedSize(compressedBlob.size);
} catch (error) {
console.error('Image compression failed:', error);
} finally {
setProcessing(false);
}
}
return (
<div>
<input
type="file"
accept="image/jpeg,image/png"
disabled={processing}
onChange={handleFileChange}
/>
{processing && <p>Compressing image...</p>}
{previewUrl && (
<div>
<p>Original size: {originalSize} bytes</p>
<p>Compressed size: {compressedSize} bytes</p>
<img
src={previewUrl}
alt="Compressed preview"
style={{ maxWidth: '100%' }}
/>
</div>
)}
</div>
);
}Next.js Usage
When using the package inside a Next.js App Router project, compression should run in a Client Component.
'use client';
import { useState } from 'react';
import {
compress_to_jpeg
} from 'image_compressor_wasm';
export default function ImageCompressor() {
const [compressedFile, setCompressedFile] = useState(null);
const [processing, setProcessing] = useState(false);
async function handleFileChange(event) {
const file = event.target.files?.[0];
if (!file) {
return;
}
setProcessing(true);
try {
const inputBuffer = await file.arrayBuffer();
const input = new Uint8Array(inputBuffer);
const output = compress_to_jpeg(input);
const result = new File(
[output],
'compressed.jpg',
{
type: 'image/jpeg',
lastModified: Date.now()
}
);
setCompressedFile(result);
} catch (error) {
console.error('Image compression failed:', error);
} finally {
setProcessing(false);
}
}
return (
<div>
<input
type="file"
accept="image/jpeg,image/png"
disabled={processing}
onChange={handleFileChange}
/>
{processing && <p>Compressing image...</p>}
{compressedFile && (
<p>
Compressed file size: {compressedFile.size} bytes
</p>
)}
</div>
);
}Uploading a Compressed Image
The compressed output can be converted to a File and uploaded using FormData.
import {
compress_to_jpeg
} from 'image_compressor_wasm';
async function compressAndUpload(file) {
const inputBuffer = await file.arrayBuffer();
const input = new Uint8Array(inputBuffer);
const output = compress_to_jpeg(input);
const compressedFile = new File(
[output],
'compressed.jpg',
{
type: 'image/jpeg',
lastModified: Date.now()
}
);
const formData = new FormData();
formData.append('image', compressedFile);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error(`Upload failed with status ${response.status}`);
}
return response.json();
}Downloading a Compressed Image
Use an object URL to download the result directly
