import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs"; /** `@napi-rs/canvas` is an optional dependency; null when its native binary is not installed. */ export async function loadCanvas(): Promise { try { return await import("@napi-rs/canvas"); } catch { return null; } } /** Number of non-white pixels in the box (x0,y0,x1,y1 in pt from the top-left) of page 1 drawn at `scale`. */ export async function inkPixels( canvasLib: typeof import("@napi-rs/canvas"), bytes: Uint8Array, box: { x0: number; y0: number; x1: number; y1: number }, scale = 2, ): Promise { const task = getDocument({ data: new Uint8Array(bytes), useSystemFonts: false, disableFontFace: true }); const doc = await task.promise; try { const page = await doc.getPage(1); const viewport = page.getViewport({ scale }); const canvas = canvasLib.createCanvas(Math.ceil(viewport.width), Math.ceil(viewport.height)); const ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; ctx.fillRect(0, 0, canvas.width, canvas.height); await page.render({ canvasContext: ctx as never, canvas: canvas as never, viewport }).promise; const x = Math.floor(box.x0 * scale); const y = Math.floor(box.y0 * scale); const w = Math.ceil((box.x1 - box.x0) * scale); const h = Math.ceil((box.y1 - box.y0) * scale); const data = ctx.getImageData(x, y, w, h).data; let ink = 0; for (let i = 0; i < data.length; i += 4) if (data[i] < 250 || data[i + 1] < 250 || data[i + 2] < 250) ink++; return ink; } finally { await task.destroy(); } } /** PNG of one page (1-based) at `scale`, white background; for visual review only. */ export async function pagePng(canvasLib: typeof import("@napi-rs/canvas"), bytes: Uint8Array, pageNo: number, scale = 1.5): Promise { const task = getDocument({ data: new Uint8Array(bytes), useSystemFonts: false, disableFontFace: true }); const doc = await task.promise; try { const page = await doc.getPage(pageNo); const viewport = page.getViewport({ scale }); const canvas = canvasLib.createCanvas(Math.ceil(viewport.width), Math.ceil(viewport.height)); const ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; ctx.fillRect(0, 0, canvas.width, canvas.height); await page.render({ canvasContext: ctx as never, canvas: canvas as never, viewport }).promise; return canvas.toBuffer("image/png"); } finally { await task.destroy(); } }