UNPKG

@pdfme/converter

Version:

TypeScript base PDF generator and React base UI. Open source, developed by the community, and completely free to use under the MIT license!

124 lines (123 loc) 4.32 kB
import { mm2pt, pt2mm } from "@pdfme/common"; import { PDFDocument } from "@pdfme/pdf-lib"; //#region src/pdf2img.ts async function pdf2img(pdf, options = {}, env) { try { const { scale = 1, imageType = "jpeg", range = {} } = options; const { start = 0, end = Infinity } = range; const { getDocument, destroyDocument, createCanvas, canvasToArrayBuffer } = env; const pdfDoc = await getDocument(pdf); try { const numPages = pdfDoc.numPages; const startPage = Math.max(start + 1, 1); const endPage = Math.min(end + 1, numPages); const results = []; for (let pageNum = startPage; pageNum <= endPage; pageNum++) { const page = await pdfDoc.getPage(pageNum); const viewport = page.getViewport({ scale }); const canvas = createCanvas(viewport.width, viewport.height); if (!canvas) throw new Error("Failed to create canvas"); const context = canvas.getContext("2d"); if (!context) throw new Error("Failed to get canvas context"); await page.render({ canvas, canvasContext: context, viewport }).promise; const arrayBuffer = canvasToArrayBuffer(canvas, imageType); results.push(arrayBuffer); } return results; } finally { await destroyDocument?.(pdfDoc); } } catch (error) { throw new Error(`[@pdfme/converter] pdf2img failed: ${error.message}`); } } //#endregion //#region src/pdf2size.ts async function pdf2size(pdf, options = {}, env) { const { scale = 1 } = options; const { getDocument, destroyDocument } = env; const pdfDoc = await getDocument(pdf); try { return await Promise.all(Array.from({ length: pdfDoc.numPages }, async (_, i) => { return await pdfDoc.getPage(i + 1).then((page) => { const { height, width } = page.getViewport({ scale, rotation: 0 }); return { height: pt2mm(height), width: pt2mm(width) }; }); })); } finally { await destroyDocument?.(pdfDoc); } } //#endregion //#region src/img2pdf.ts function detectImageType(buffer) { const bytes = new Uint8Array(buffer); if (bytes.length >= 2 && bytes[0] === 255 && bytes[1] === 216) return "jpeg"; if (bytes.length >= 8 && bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71 && bytes[4] === 13 && bytes[5] === 10 && bytes[6] === 26 && bytes[7] === 10) return "png"; return "unknown"; } async function img2pdf(imgs, options = {}) { try { const { scale = 1, size, margin = [ 0, 0, 0, 0 ] } = options; if (!Array.isArray(imgs) || imgs.length === 0) throw new Error("Input must be a non-empty array of image buffers"); const doc = await PDFDocument.create(); for (const img of imgs) try { let image; const type = detectImageType(img); if (type === "jpeg") image = await doc.embedJpg(img); else if (type === "png") image = await doc.embedPng(img); else try { image = await doc.embedJpg(img); } catch { image = await doc.embedPng(img); } const page = doc.addPage(); const { width: imgWidth, height: imgHeight } = image.scale(scale); const pageWidth = size ? mm2pt(size.width) : imgWidth; const pageHeight = size ? mm2pt(size.height) : imgHeight; page.setSize(pageWidth, pageHeight); const [topMargin, rightMargin, bottomMargin, leftMargin] = margin.map(mm2pt); const availableWidth = pageWidth - leftMargin - rightMargin; const availableHeight = pageHeight - topMargin - bottomMargin; const widthRatio = availableWidth / imgWidth; const heightRatio = availableHeight / imgHeight; const ratio = Math.min(widthRatio, heightRatio, 1); const finalWidth = imgWidth * ratio; const finalHeight = imgHeight * ratio; const x = leftMargin + (availableWidth - finalWidth) / 2; const y = bottomMargin + (availableHeight - finalHeight) / 2; page.drawImage(image, { x, y, width: finalWidth, height: finalHeight }); } catch (error) { throw new Error(`Failed to process image: ${error.message}`); } const pdfUint8Array = await doc.save(); const buffer = new ArrayBuffer(pdfUint8Array.byteLength); new Uint8Array(buffer).set(pdfUint8Array); return buffer; } catch (error) { throw new Error(`[@pdfme/converter] img2pdf failed: ${error.message}`); } } //#endregion export { pdf2size as n, pdf2img as r, img2pdf as t }; //# sourceMappingURL=img2pdf-Ca1yX5Sv.js.map