UNPKG

pdf-to-png-converter-allow-yarn

Version:

Node.js utility to convert PDF file/buffer pages to PNG files/buffers with no native dependencies.

96 lines (95 loc) 4.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pdfToPng = pdfToPng; const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const const_1 = require("./const"); const propsToPdfDocInitParams_1 = require("./propsToPdfDocInitParams"); const node_canvas_factory_1 = require("./node.canvas.factory"); /** * Converts a PDF file to PNG images. * * @param pdfFile - The path to the PDF file or a buffer containing the PDF data. * @param props - Optional properties to customize the conversion process. * @returns A promise that resolves to an array of PNG page outputs. * * @throws Will throw an error if invalid pages are requested when `strictPagesToProcess` is true. * * @example * ```typescript * const pngPages = await pdfToPng('/path/to/pdf/file.pdf', { * pagesToProcess: [1, 2, 3], * outputFolder: '/path/to/output/folder', * viewportScale: 2.0, * outputFileMaskFunc: (pageNumber) => `custom_name_page_${pageNumber}.png`, * }); * ``` */ async function pdfToPng(pdfFile, props) { const isBuffer = Buffer.isBuffer(pdfFile); const pdfFileBuffer = isBuffer ? pdfFile : (await node_fs_1.promises.readFile(pdfFile)).buffer; const pdfDocument = await getPdfDocument(pdfFileBuffer, props); // Get the pages to process based on the provided options, invalid pages will be filtered out const pagesToProcess = props?.pagesToProcess ?? Array.from({ length: pdfDocument.numPages }, (_, index) => index + 1); const pngPagesOutput = []; try { // Process each page in parallel const pngPageOutputs = await Promise.all(pagesToProcess // Filter out invalid page numbers .filter((pageNumber) => pageNumber <= pdfDocument.numPages && pageNumber >= 1) // Process the page .map((pageNumber) => { const pageViewportScale = props?.viewportScale !== undefined ? props.viewportScale : const_1.PDF_TO_PNG_OPTIONS_DEFAULTS.viewportScale; const defaultMask = isBuffer ? const_1.PDF_TO_PNG_OPTIONS_DEFAULTS.outputFileMask : (0, node_path_1.parse)(pdfFile).name; const pageName = props?.outputFileMaskFunc?.(pageNumber) ?? `${defaultMask}_page_${pageNumber}.png`; return processPdfPage(pdfDocument, pageName, pageNumber, pageViewportScale); })); pngPagesOutput.push(...pngPageOutputs); } finally { await pdfDocument.cleanup(); } // Save the PNG files to the output folder if (props?.outputFolder) { await node_fs_1.promises.mkdir(props.outputFolder, { recursive: true }); for (const pngPageOutput of pngPagesOutput) { pngPageOutput.path = (0, node_path_1.resolve)(props.outputFolder, pngPageOutput.name); await node_fs_1.promises.writeFile(pngPageOutput.path, pngPageOutput.content); pngPageOutput.path = (0, node_path_1.resolve)(props.outputFolder, pngPageOutput.name); } } return pngPagesOutput; } /** * Asynchronously retrieves a PDF document from a given ArrayBuffer. * * @param pdfFileBuffer - The buffer containing the PDF file data. * @param props - Optional properties to customize the PDF document initialization. * @returns A promise that resolves to a PDFDocumentProxy object representing the PDF document. */ async function getPdfDocument(pdfFileBuffer, props) { const { getDocument } = await import('pdfjs-dist/legacy/build/pdf.mjs'); const documentInitParameters = (0, propsToPdfDocInitParams_1.propsToPdfDocInitParams)(props); return await getDocument({ ...documentInitParameters, data: new Uint8Array(pdfFileBuffer), }).promise; } async function processPdfPage(pdfDocument, pageName, pageNumber, pageViewportScale) { const page = await pdfDocument.getPage(pageNumber); const viewport = page.getViewport({ scale: pageViewportScale }); const canvasFactory = new node_canvas_factory_1.NodeCanvasFactory(); const { canvas, context } = canvasFactory.create(viewport.width, viewport.height); await page.render({ canvasContext: context, viewport }).promise; const pngPageOutput = { pageNumber, name: pageName, content: canvas.toBuffer('image/png'), path: '', width: viewport.width, height: viewport.height, }; page.cleanup(); canvasFactory.destroy({ canvas, context }); return pngPageOutput; }