UNPKG

mindee

Version:

Mindee Client Library for Node.js

94 lines (93 loc) 3.24 kB
import tmp from "tmp"; import * as fs from "node:fs"; import { MindeePdfError } from "../errors/index.js"; import { loadOptionalDependency } from "../dependency/index.js"; import { logger } from "../logger.js"; function getConcatenatedText(pages) { return pages.flatMap(page => page.content.map(item => item.str)).join(" "); } /** * Extracts text from a full PDF document. * * @returns A Promise containing the extracted text as a string. * @param pdfBuffer PDF handle, as a buffer. */ export async function extractTextFromPdf(pdfBuffer) { const pdfJsExtract = await loadOptionalDependency("pdf.js-extract", "PDF text extraction"); const pdfJs = pdfJsExtract.pdfjs || pdfJsExtract; const pdfExtract = new pdfJs.PDFExtract(); const options = {}; const pdf = await new Promise((resolve, reject) => { pdfExtract.extractBuffer(pdfBuffer, options, (err, result) => { if (err) reject(err); if (result === undefined) reject(new MindeePdfError("Couldn't process result.")); else resolve(result); }); }); const pages = pdf.pages.map((page, index) => ({ pageNumber: index + 1, content: page.content.map((item) => ({ str: item.str, x: item.x, y: item.y, width: item.width, height: item.height, fontName: item.fontName, })), })); return { pages, getConcatenatedText: () => getConcatenatedText(pages), }; } /** * Checks if a PDF contains source text. * * @param pdfData Buffer representing the content of the PDF file. * * @returns A Promise containing a boolean indicating if the PDF has source text. */ export async function hasSourceText(pdfData) { const text = await extractTextFromPdf(pdfData); return text.getConcatenatedText().trim().length > 0; } /** * Rasterizes a PDF page. * * @param pdfData Buffer representation of the entire PDF file. * @param index Index of the page to rasterize. * @param quality Quality to apply during rasterization. * @return Buffer containing the rasterized image data. */ export async function rasterizePage(pdfData, index, quality = 85) { const popplerImport = await loadOptionalDependency("node-poppler", "Image Processing"); const poppler = popplerImport.default || popplerImport; const popplerInstance = new poppler.Poppler(); const tmpPdf = tmp.fileSync(); const tempPdfPath = tmpPdf.name; const antialiasOption = "best"; try { await fs.promises.writeFile(tempPdfPath, pdfData); const options = { antialias: antialiasOption, firstPageToConvert: index, lastPageToConvert: index, jpegFile: true, jpegOptions: `quality=${quality}`, singleFile: true }; const jpegBuffer = await popplerInstance.pdfToCairo(tempPdfPath, undefined, options); await fs.promises.unlink(tempPdfPath); return Buffer.from(jpegBuffer, "binary"); } catch (error) { logger.error("Error rasterizing PDF:", error); throw error; } finally { tmpPdf.removeCallback(); } }