u
This commit is contained in:
57
src/workers/imageWorker.js
Normal file
57
src/workers/imageWorker.js
Normal file
@@ -0,0 +1,57 @@
|
||||
self.onmessage = async (e) => {
|
||||
const { id, file, maxDim = 1000, quality = 0.85 } = e.data;
|
||||
|
||||
try {
|
||||
// Step 1: Get original dimensions without full pixel context decoding
|
||||
const tempBitmap = await createImageBitmap(file);
|
||||
const { width, height } = tempBitmap;
|
||||
tempBitmap.close(); // Immediately release memory
|
||||
|
||||
// Step 2: Calculate target dimensions preserving aspect ratio
|
||||
let targetWidth = width;
|
||||
let targetHeight = height;
|
||||
|
||||
if (width > maxDim || height > maxDim) {
|
||||
if (width > height) {
|
||||
targetWidth = maxDim;
|
||||
targetHeight = Math.round((height * maxDim) / width);
|
||||
} else {
|
||||
targetHeight = maxDim;
|
||||
targetWidth = Math.round((width * maxDim) / height);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 3: Decode and scale natively via createImageBitmap on GPU
|
||||
const resizedBitmap = await createImageBitmap(file, {
|
||||
resizeWidth: targetWidth,
|
||||
resizeHeight: targetHeight,
|
||||
resizeQuality: 'high',
|
||||
});
|
||||
|
||||
// Step 4: Draw to OffscreenCanvas
|
||||
const canvas = new OffscreenCanvas(targetWidth, targetHeight);
|
||||
const ctx = canvas.getContext('2d', {
|
||||
alpha: true,
|
||||
desynchronized: true,
|
||||
});
|
||||
|
||||
ctx.drawImage(resizedBitmap, 0, 0);
|
||||
resizedBitmap.close(); // Clean up GPU memory
|
||||
|
||||
// Step 5: Native C++ WebP encoding directly to Blob
|
||||
const webpBlob = await canvas.convertToBlob({
|
||||
type: 'image/webp',
|
||||
quality,
|
||||
});
|
||||
|
||||
self.postMessage({
|
||||
id,
|
||||
success: true,
|
||||
blob: webpBlob,
|
||||
width: targetWidth,
|
||||
height: targetHeight,
|
||||
});
|
||||
} catch (error) {
|
||||
self.postMessage({ id, success: false, error: error?.message || String(error) });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user