pdf-to-png-converter
Version:
Node.js utility to convert PDF file/buffer pages to PNG files/buffers. No build-time compilation required — pre-built native binaries included for all major platforms.
153 lines (152 loc) • 8.2 kB
TypeScript
import type { VerbosityLevel } from '../types/index.js';
/**
* Options for the `pdfToPng` conversion function.
*
* All properties are optional. Any unset property falls back to the corresponding
* value in `PDF_TO_PNG_OPTIONS_DEFAULTS` defined in `src/const.ts`.
*/
export interface PdfToPngOptions {
/**
* Scale factor applied to each page viewport before rendering.
* Values above `1` produce larger, higher-resolution images; values below `1` produce smaller images.
* Must be a finite positive number. Maximum allowed value is `100`; values above this limit throw
* immediately to prevent runaway memory allocation (OOM) during canvas creation.
* Default: `1`.
*/
viewportScale?: number;
/**
* When `true`, pdfjs will not load embedded fonts and substitutes them with built-in fonts.
* Speeds up rendering but may affect visual fidelity for PDFs with custom fonts.
* Default: `true`.
*/
disableFontFace?: boolean;
/**
* When `true`, pdfjs attempts to use fonts installed on the host system.
* Typically combined with `disableFontFace: false` to improve font rendering accuracy.
* Default: `false`.
*/
useSystemFonts?: boolean;
/**
* When `true`, pdfjs processes XFA (XML Forms Architecture) form data embedded in the PDF.
* Default: `true`.
*/
enableXfa?: boolean;
/**
* Password for opening password-protected (encrypted) PDFs.
* Leave `undefined` for unprotected files.
* Default: `undefined`.
*/
pdfFilePassword?: string;
/**
* Folder path (relative or absolute) where PNG files will be written.
* Relative paths are resolved against `process.cwd()`.
* The folder is created recursively if it does not exist.
* When omitted, no files are written to disk.
*
* @remarks
* **Security (TOCTOU):** The write-containment guard rejects filenames that contain path
* separators (so the target is always a direct child of this folder), resolves symlinks,
* checks that the output path stays within this folder, and uses exclusive-create file opens
* to avoid overwriting pre-existing files or following a pre-planted target symlink at the
* final filename. To reduce exposure on multi-user or shared systems, ensure this directory
* is private and not writable by untrusted users.
*/
outputFolder?: string;
/**
* Custom naming function for output PNG files.
* Receives the 1-based page number and must return a full filename string including the `.png` extension
* (e.g. `(pageNumber) => \`page_${pageNumber}.png\``).
* When omitted, names default to `<pdfBasename>_page_<pageNumber>.png`,
* or `buffer_page_<pageNumber>.png` when the PDF is supplied as an `ArrayBufferLike`.
* @since 3.14.0
*/
outputFileMaskFunc?: (pageNumber: number) => string;
/**
* 1-based integer page numbers to convert. Non-integer values and values less than or equal to zero throw immediately.
* Pages above the document page count are silently ignored.
* When omitted, all pages in the document are processed.
* @since 3.3.0
*/
pagesToProcess?: number[];
/**
* pdfjs verbosity level. Use the `VerbosityLevel` const for readable values:
* `VerbosityLevel.ERRORS` (0), `VerbosityLevel.WARNINGS` (1), `VerbosityLevel.INFOS` (5).
* Default: `VerbosityLevel.ERRORS` (0).
*/
verbosityLevel?: VerbosityLevel;
/**
* When `true`, each `PngPageOutput` will include a `content` property containing the PNG image as a `Buffer`.
* Set to `false` to skip buffering when only writing files to disk, which reduces memory usage.
* Default: `true`.
*/
returnPageContent?: boolean;
/**
* When `true`, only page metadata is returned for each page without rendering any PNG image.
* The returned `PngPageOutput` objects will have `pageNumber`, `name`, `width`, `height`, and
* `rotation` populated, but `content` will always be `undefined` and `path` will always be `""`.
* No canvas is created, no rendering is performed, and no files are written to disk even if
* `outputFolder` is set.
* This is significantly faster than full rendering and useful for inspecting page dimensions
* and rotation without generating images.
* To stay consistent with a real render, this path still rejects pages that could not be
* rendered at the requested `viewportScale` — both those that floor to `0` px and those whose
* rendered (floored) canvas area exceeds the internal canvas pixel limit — rather than reporting
* dimensions for a page that would throw on render.
* Default: `false`.
* @since 3.14.0
*/
returnMetadataOnly?: boolean;
/**
* When `true`, selected pages are rendered concurrently through a sliding-window scheduler
* that keeps up to `concurrencyLimit` pages active. When `false`, pages are processed in
* a lightly pipelined sequence: results are always returned in page order, but the PNG
* encoding and disk writes of finished pages may overlap the rendering of the next page
* (at most three pages in flight), so files may finish writing out of page order and, when
* a page fails, pages already in flight still complete before the returned promise rejects.
* Consume output via the resolved `PngPageOutput[]` (ordered) rather than directory-watch order.
* Peak canvas memory in this mode is up to three live canvases; for strict one-page-at-a-time
* processing with a single live canvas, set `processPagesInParallel: true` with
* `concurrencyLimit: 1` (a sliding window of exactly one page).
* Default: `false`.
* @since 3.7.0
*/
processPagesInParallel?: boolean;
/**
* Maximum number of pages rendered simultaneously when `processPagesInParallel` is `true`.
* Must be a positive integer between `1` and `16` (inclusive); values outside that range throw
* immediately (before any I/O). The upper bound caps peak in-flight canvas memory at roughly
* `16 × MAX_CANVAS_PIXELS × 4 bytes ≈ 6.4 GiB` so a single conversion cannot exhaust container
* memory. Higher values increase throughput at the cost of memory. Applies when
* `processPagesInParallel` or `renderInWorkerThreads` is enabled; in worker-thread mode it
* sets the worker-pool size.
* Default: `4`.
* @since 3.14.0
*/
concurrencyLimit?: number;
/**
* When `true`, pages are rasterized in a pool of Node.js worker threads (pool size =
* `concurrencyLimit`), giving true multi-core parallelism — unlike `processPagesInParallel`,
* which interleaves pages on one thread. Each worker loads its own copy of the document, so
* expect roughly one PDF copy plus one pdf.js instance of memory per worker and a pool
* startup cost of a few hundred milliseconds per conversion; it pays off on multi-page,
* render-heavy (e.g. image-heavy) documents and can be slower for small ones.
* Rendered pixels are identical to single-threaded mode; results are returned in page
* order; disk writes still happen on the main thread through the same path-security guards.
* Takes precedence over `processPagesInParallel`. Ignored when `returnMetadataOnly` is `true`
* (metadata extraction does not render). `outputFileMaskFunc` is fully supported — names are
* resolved on the main thread before dispatch.
* Default: `false`.
* @since 4.2.0
*/
renderInWorkerThreads?: boolean;
/**
* Maximum allowed input PDF size in bytes. Inputs larger than this throw immediately,
* before any rendering work is started. Applies to both the file path branch (validated via
* `fs.stat()`) and the buffer / `Uint8Array` branch (validated via `byteLength`). The path
* branch additionally rejects non-regular files (FIFOs, sockets, character devices such as
* `/dev/zero`) to prevent unbounded reads. Must be a positive integer.
* Default: `256 * 1024 * 1024` (256 MiB).
* @since 4.1.0
*/
maxInputBytes?: number;
}