diff --git a/src/utils/scan-renderer/canvas-scan/scan-canvas.ts b/src/utils/scan-renderer/canvas-scan/scan-canvas.ts index 3c36e44d..a14a6a5e 100644 --- a/src/utils/scan-renderer/canvas-scan/scan-canvas.ts +++ b/src/utils/scan-renderer/canvas-scan/scan-canvas.ts @@ -55,21 +55,21 @@ export async function scanCanvas( ctx.drawImage(img, 0, 0); - if (config.noise !== 0) { - const noiseSVG = getNoiseSVG(config.noise); - const noiseSVGBlob = new Blob([noiseSVG], { type: "image/svg+xml" }); - const noiseSVGURL = URL.createObjectURL(noiseSVGBlob); + // if (config.noise !== 0) { + // const noiseSVG = getNoiseSVG(config.noise); + // const noiseSVGBlob = new Blob([noiseSVG], { type: "image/svg+xml" }); + // const noiseSVGURL = URL.createObjectURL(noiseSVGBlob); - const noiseImg = new Image(); - noiseImg.src = noiseSVGURL; - await new Promise((resolve) => (noiseImg.onload = resolve)); - if (signal?.aborted) { - throw new Error("Aborted"); - } + // const noiseImg = new Image(); + // noiseImg.src = noiseSVGURL; + // await new Promise((resolve) => (noiseImg.onload = resolve)); + // if (signal?.aborted) { + // throw new Error("Aborted"); + // } - // add noise - ctx.drawImage(noiseImg, -width, -height, width * 2, height * 2); - } + // // add noise + // ctx.drawImage(noiseImg, -width, -height, width * 2, height * 2); + // } if (config.border) { ctx.strokeStyle = "black"; diff --git a/src/utils/scan-renderer/canvas-scan/scan.worker.ts b/src/utils/scan-renderer/canvas-scan/scan.worker.ts new file mode 100644 index 00000000..19332d00 --- /dev/null +++ b/src/utils/scan-renderer/canvas-scan/scan.worker.ts @@ -0,0 +1,15 @@ +import type { ScanConfig } from "./types"; +import { scanCanvas } from "./scan-canvas"; + +export interface WorkerMessage { + page: Blob; + config: ScanConfig; +} + +onmessage = async (e: MessageEvent) => { + const { page, config } = e.data; + const canvas = new OffscreenCanvas(1000, 1000); + await scanCanvas(canvas, page, config); + const blob = await canvas.convertToBlob({ type: config.output_format }); + postMessage(blob); +}; diff --git a/src/utils/scan-renderer/canvas-scan/scanner.ts b/src/utils/scan-renderer/canvas-scan/scanner.ts index 2ea2e7df..323c84de 100644 --- a/src/utils/scan-renderer/canvas-scan/scanner.ts +++ b/src/utils/scan-renderer/canvas-scan/scanner.ts @@ -1,6 +1,7 @@ import { scanCanvas } from "./scan-canvas"; import type { ScanConfig } from "./types"; import type { ScanRenderer } from "../types"; +import ScanWorker from "./scan.worker?worker"; export class CanvasScanner implements ScanRenderer { config: ScanConfig; @@ -16,31 +17,32 @@ export class CanvasScanner implements ScanRenderer { } ): Promise<{ blob: Blob; - height: number; - width: number; }> { if (options?.signal?.aborted) { throw new Error("Aborted"); } - const canvas = document.createElement("canvas"); - await scanCanvas(canvas, image, this.config); - if (options?.signal?.aborted) { - throw new Error("Aborted"); - } + const uuid = Math.random().toString(36).substring(2, 15); + + console.time(`scanCanvas ${uuid}`); + const worker = new ScanWorker(); + const blob = await new Promise((resolve, reject) => { + worker.onmessage = (e) => { + resolve(e.data); + worker.terminate(); + }; + worker.onerror = (e) => { + console.error(e); + reject(e); + worker.terminate(); + }; + worker.postMessage({ + page: image, + config: JSON.parse(JSON.stringify(this.config)), + }); + }); + console.timeEnd(`scanCanvas ${uuid}`); - const blob = await new Promise((resolve, reject) => - canvas.toBlob((blob) => { - if (blob) { - resolve(blob); - } else { - reject(new Error("Canvas to Blob failed")); - } - }, this.config.output_format) - ); - const height = canvas.height; - const width = canvas.width; - canvas.remove(); - return { blob, height, width }; + return { blob }; } }