JSFiddle - React, Tailwind, and code Playground
Local File Image Viewer with Web Worker, Offscreen Canvas, and Image Scaling
by skibulk
HTML
<input id="browse" name="files[]" type="file" multiple/>
CSS
canvas {
display: block;
}
JavaScript
/* To-Do:
*/
console.clear();
// Canvas-supported image-format MIME types
var canvasImageTypes = ["image/bmp", "image/gif", "image/jpeg", "image/png", "image/svg", "image/webp"]
// Image Queue and Worker Status
var queue = [];
var running = false;
// Initialize Web Worker
var myWorker = toWorker(imageProcessor);
// Handle Web Worker Output
myWorker.onmessage = function(event) {
var bitmap = event.data;
// console.log("Received Image Data at Root", bitmap);
// Create Canvas element
var myCanvas = document.createElement("canvas");
myCanvas.width = bitmap.width;
myCanvas.height = bitmap.height;
// Add image to canvas and canvas to DOM
var context = myCanvas.getContext("bitmaprenderer");
context.transferFromImageBitmap(bitmap);
document.body.appendChild(myCanvas);
processQueue();
};
// Browse Button
var browse = document.getElementById("browse");
// Handle file selection
browse.onchange = function(event) {
for ( i = 0; i < event.target.files.length; i++ )
{
var file = event.target.files[i];
if (canvasImageTypes.includes(file.type)) {
queue.push(file);
}
}
if ( !running ) processQueue();
}
// Queue Manager
function processQueue() {
if ( queue.length ) {
running = true;
var file = queue.shift();
// console.log( file );
myWorker.postMessage(file);
} else {
running = false;
}
}
// Web Worker - Read an image file, Draw it to an Offscreen Canvas, Resize, and transfer to parent context
function imageProcessor() {
// Process image file
onmessage = async function(event) {
// console.log("imageReader Received a File", event);
let image = await createImageBitmap( event.data );
var offscreen = new OffscreenCanvas( image.width, image.height);
var context = offscreen.getContext('2d');
context.drawImage( image, 0, 0 );
resample_single( offscreen, 200, 200, true );
var bitmap = offscreen.transferToImageBitmap();
...