pdf-visual-diff
Version:
Visual Regression Testing for PDFs in JavaScript
111 lines • 4.88 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.pdf2png = pdf2png;
const fs = __importStar(require("node:fs/promises"));
const path = __importStar(require("node:path"));
const jimp_1 = require("jimp");
const types_1 = require("../types");
const conversions_1 = require("../conversions");
// pdfjs location
const PDFJS_DIR = path.join(path.dirname(require.resolve('pdfjs-dist')), '..');
// Convert path to URL format (forward slashes) for pdfjs-dist compatibility on Windows
const toUrlPath = (p) => p.split(path.sep).join('/');
const DOCUMENT_INIT_PARAMS_DEFAULTS = {
// Where the standard fonts are located.
standardFontDataUrl: toUrlPath(path.join(PDFJS_DIR, 'standard_fonts')) + '/',
// Some PDFs need external cmaps.
cMapUrl: toUrlPath(path.join(PDFJS_DIR, 'cmaps')) + '/',
cMapPacked: true,
};
const pdf2PngDefOpts = {
dpi: types_1.Dpi.High,
};
const PDF_DPI = 72;
function getPageViewPort(page, dpi) {
const dpiNum = dpi === types_1.Dpi.Low ? PDF_DPI : dpi === types_1.Dpi.High ? 144 : dpi;
const viewport = page.getViewport({ scale: 1.0 });
if (dpiNum === PDF_DPI) {
return viewport;
}
// Increase resolution
const horizontalMm = (0, conversions_1.convertFromPxToMm)(viewport.width, PDF_DPI);
const verticalMm = (0, conversions_1.convertFromPxToMm)(viewport.height, PDF_DPI);
const actualWidth = (0, conversions_1.convertFromMmToPx)(horizontalMm, dpiNum);
const actualHeight = (0, conversions_1.convertFromMmToPx)(verticalMm, dpiNum);
const scale = Math.min(actualWidth / viewport.width, actualHeight / viewport.height);
return page.getViewport({ scale });
}
function mkPdfPagesRenderer(pdfDocument, dpi) {
return async function (toImage, toJimpInstances) {
const images = [];
const totalPages = pdfDocument.numPages;
for (let idx = 1; idx <= totalPages; idx += 1) {
const page = await pdfDocument.getPage(idx);
const canvasFactory = pdfDocument.canvasFactory;
const viewport = getPageViewPort(page, dpi);
// @ts-expect-error unknown method on Object
const canvasAndContext = canvasFactory.create(viewport.width, viewport.height);
const renderParameters = {
// pdf.js expects a DOM canvas, but the node build returns a napi-rs canvas.
// Cast here to satisfy the newer RenderParameters typing.
canvas: canvasAndContext.canvas,
canvasContext: canvasAndContext.context,
viewport,
};
await page.render(renderParameters).promise;
images.push(toImage(canvasAndContext.canvas));
page.cleanup();
}
return toJimpInstances(images);
};
}
async function pdf2png(pdf, options = {}) {
const { getDocument } = await import('pdfjs-dist/legacy/build/pdf.mjs');
const opts = {
...pdf2PngDefOpts,
...options,
};
// Load PDF
const pdfBuffer = Buffer.isBuffer(pdf) ? pdf : await fs.readFile(pdf);
const loadingTask = getDocument({
...DOCUMENT_INIT_PARAMS_DEFAULTS,
data: new Uint8Array(pdfBuffer),
});
const pdfDocument = await loadingTask.promise;
const renderPdfPages = mkPdfPagesRenderer(pdfDocument, opts.dpi);
return renderPdfPages((canvas) => canvas.toBuffer('image/png'), (images) => Promise.all(images.map((x) => jimp_1.Jimp.read(x).then((x) => x))));
}
//# sourceMappingURL=pdf2png.js.map