import * as pdfjsLib from "pdfjs-dist" import pdfWorkerSrc from "pdfjs-dist/build/pdf.worker.mjs?url" import { PAGE_WIDTH } from "../../../utils/exam-canvas/model" pdfjsLib.GlobalWorkerOptions.workerSrc = pdfWorkerSrc export interface PdfPageImage { pageNumber: number src: string width: number height: number } export async function loadPdfPageImages( pdfBytes: ArrayBuffer, targetWidth = PAGE_WIDTH, onPageReady?: (pages: PdfPageImage[]) => void, ): Promise { const pdf = await pdfjsLib.getDocument({ data: new Uint8Array(pdfBytes) }).promise const pages: PdfPageImage[] = [] // Reuse a single canvas across all pages to avoid allocating ~120 MB of canvas memory // for a typical 36-page exam paper. const canvas = document.createElement("canvas") for (let pageNumber = 1; pageNumber <= pdf.numPages; pageNumber += 1) { const page = await pdf.getPage(pageNumber) const baseViewport = page.getViewport({ scale: 1 }) const scale = targetWidth / baseViewport.width const viewport = page.getViewport({ scale }) canvas.width = Math.ceil(viewport.width) canvas.height = Math.ceil(viewport.height) const context = canvas.getContext("2d") if (!context) throw new Error("Unable to create PDF render canvas") context.clearRect(0, 0, canvas.width, canvas.height) await page.render({ canvasContext: context, viewport }).promise pages.push({ pageNumber, src: canvas.toDataURL("image/png"), width: canvas.width, height: canvas.height, }) onPageReady?.([...pages]) } return pages }