绘制图像
2025年02月10日
一、认识
二、实现
2.1 URL 格式传输
主线程
const worker = new Worker("./worker.js");
const image = document.getElementById("img");
const canvas = document.getElementById("canvas");
const offscreenCanvas = new OffscreenCanvas(canvas.width, canvas.height);
// 将图片的 URL 和 OffscreenCanvas 传递给 Worker
worker.postMessage({ canvas: offscreenCanvas, imageUrl: image.src }, [offscreenCanvas]);
worker.onmessage = (event) => {
const { bitmap, error } = event.data;
if (error) {
console.error("Worker error:", error);
return;
}
if (bitmap) {
const mainCanvasContext2d = canvas.getContext("2d");
mainCanvasContext2d.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
}
};
worker.onerror = (error) => {
console.error("Worker error:", error);
};
Worker
async function draw(canvas, imageUrl) {
try {
const ctx2D = canvas.getContext("2d");
// 加载图片
const image = await loadImage(imageUrl);
// 绘制图片到 OffscreenCanvas
ctx2D.drawImage(image, 0, 0, canvas.width, canvas.height);
// 将 OffscreenCanvas 转换为 ImageBitmap
const bitmap = await canvas.transferToImageBitmap();
self.postMessage({ bitmap });
} catch (error) {
self.postMessage({ error: error.message });
}
}
// 加载图片的辅助函数
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = (error) => reject(error);
img.src = url;
});
}
self.onmessage = (event) => {
const { canvas, imageUrl } = event.data;
draw(canvas, imageUrl);
};
2.2 ArrayBuffer 格式传输
主线程
const worker = new Worker("./worker.js");
const image = document.getElementById("img");
const canvas = document.getElementById("canvas");
const offscreenCanvas = new OffscreenCanvas(canvas.width, canvas.height);
// 将图片转换为 Blob
fetch(image.src)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader();
reader.onload = () => {
const buffer = reader.result;
// 将 ArrayBuffer 和 OffscreenCanvas 传递给 Worker
worker.postMessage({ canvas: offscreenCanvas, buffer }, [offscreenCanvas]);
};
reader.readAsArrayBuffer(blob);
});
worker.onmessage = (event) => {
const { bitmap, error } = event.data;
if (error) {
console.error("Worker error:", error);
return;
}
if (bitmap) {
const mainCanvasContext2d = canvas.getContext("2d");
mainCanvasContext2d.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
}
};
worker.onerror = (error) => {
console.error("Worker error:", error);
};
Worker
async function draw(canvas, buffer) {
try {
const ctx2D = canvas.getContext("2d");
// 将 ArrayBuffer 转换为 Blob
const blob = new Blob([buffer]);
// 使用 createImageBitmap 将 Blob 转换为 ImageBitmap
const imageBitmap = await createImageBitmap(blob);
// 绘制 ImageBitmap 到 OffscreenCanvas
ctx2D.drawImage(imageBitmap, 0, 0, canvas.width, canvas.height);
// 将 OffscreenCanvas 转换为 ImageBitmap
const newBitmap = await canvas.transferToImageBitmap();
self.postMessage({ bitmap: newBitmap });
} catch (error) {
self.postMessage({ error: error.message });
}
}
self.onmessage = (event) => {
const { canvas, buffer } = event.data;
draw(canvas, buffer);
};
2.3 ImageBitmap 格式传输
主线程
const worker = new Worker("./worker.js");
const image = document.getElementById("img");
const canvas = document.getElementById("canvas");
const offscreenCanvas = new OffscreenCanvas(canvas.width, canvas.height);
// 将图片转换为 ImageBitmap
createImageBitmap(image).then(bitmap => {
// 将 ImageBitmap 和 OffscreenCanvas 传递给 Worker
worker.postMessage({ canvas: offscreenCanvas, bitmap }, [offscreenCanvas, bitmap]);
});
worker.onmessage = (event) => {
const { bitmap, error } = event.data;
if (error) {
console.error("Worker error:", error);
return;
}
if (bitmap) {
const mainCanvasContext2d = canvas.getContext("2d");
mainCanvasContext2d.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
}
};
worker.onerror = (error) => {
console.error("Worker error:", error);
};
Worker
async function draw(canvas, bitmap) {
try {
const ctx2D = canvas.getContext("2d");
// 绘制 ImageBitmap 到 OffscreenCanvas
ctx2D.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
// 将 OffscreenCanvas 转换为 ImageBitmap
const newBitmap = await canvas.transferToImageBitmap();
self.postMessage({ bitmap: newBitmap });
} catch (error) {
self.postMessage({ error: error.message });
}
}
self.onmessage = (event) => {
const { canvas, bitmap } = event.data;
draw(canvas, bitmap);
};