pdf-to-tiff-pure-aloka
v1.0.12
Published
Pure Node.js PDF to TIFF converter — no system dependencies, no native bindings. Uses pdfjs-dist + pureimage + utif.
Maintainers
Readme
pdf-to-tiff-pure-aloka
Pure Node.js PDF to TIFF converter — zero system dependencies, zero native bindings.
Usespdfjs-dist(Mozilla) +pureimage+ custom TIFF encoder. Works on any OS without installing Ghostscript, Poppler, or ImageMagick.
Table of Contents
- Features
- Requirements
- Installation
- Quick Start
- API Reference
- Examples
- Compression Modes
- Known Limitations
- License
Features
- ✅ 100% pure JavaScript / TypeScript — no C++ bindings, no native add-ons
- ✅ No system dependencies — no Ghostscript, Poppler, or ImageMagick required
- ✅ Three compression modes — LZW, PackBits, or uncompressed
- ✅ Barcode-safe binarization — Otsu adaptive threshold → crisp 1-bit black-and-white output
- ✅ TypeScript types included — full
.d.tsdeclarations shipped - ✅ One TIFF per PDF page —
page-1.tiff,page-2.tiff, … - ✅ PDF text extraction — extract all text from a PDF as a plain string
- ✅ MIT License — free for commercial and open-source use
Requirements
| Requirement | Version | |-------------|---------| | Node.js | ≥ 18.0.0 | | npm | ≥ 8.0.0 |
No system libraries needed.
Installation
npm install pdf-to-tiff-pure-alokaQuick Start
const { convertPdfToTiff, convertPdfToText } = require('pdf-to-tiff-pure-aloka');
async function main() {
// Convert to TIFF
const result = await convertPdfToTiff('document.pdf', './output');
if (result.success) {
console.log(`Converted ${result.convertedPages} pages:`);
result.outputFiles.forEach(f => console.log(' -', f));
} else {
console.error('Conversion failed:', result.error);
}
// Extract text
const text = await convertPdfToText('document.pdf');
console.log(text);
}
main();TypeScript:
import { convertPdfToTiff, convertPdfToText, ConversionOptions } from 'pdf-to-tiff-pure-aloka';
const options: ConversionOptions = {
scale: 2.0,
compression: 'lzw',
filePrefix: 'scan',
};
const result = await convertPdfToTiff('document.pdf', './output', options);
console.log(result.outputFiles);
// Multi-page: → ['./output/scan-1.tiff', './output/scan-2.tiff', ...]
// Single-page: → ['./output/scan.tiff']API Reference
convertPdfToTiff()
convertPdfToTiff(
pdfPath: string,
outputDir: string,
options?: ConversionOptions
): Promise<ConversionResult>Converts every page of a PDF file into individual TIFF files.
| Parameter | Type | Required | Description |
|------------|---------------------|----------|-------------|
| pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) |
| outputDir| string | ✅ Yes | Directory where TIFF files are written. Created automatically if it does not exist. |
| options | ConversionOptions | No | Optional settings (see below) |
Throws Error if:
- The PDF file does not exist or cannot be read
- The PDF is corrupt or has no pages
scaleis outside the valid range (0 < scale ≤ 10)- The output directory cannot be created
convertPdfToTiffHighFidelity()
convertPdfToTiffHighFidelity(
pdfPath: string,
outputDir: string,
options?: ConversionOptions
): Promise<ConversionResult>Converts every page of a PDF file into individual TIFF files using node-canvas (Cairo rendering backend) for high-fidelity output.
Unlike the standard convertPdfToTiff() which uses pureimage, this function leverages the Cairo graphics library via node-canvas to achieve full Canvas 2D API support. This ensures embedded images, barcodes, QR codes, and complex vector graphics are rendered accurately in the output TIFF.
Use this when:
- Your PDFs contain embedded images that must be preserved
- Barcodes and QR codes need pixel-perfect fidelity
- Complex vector graphics or gradients need accurate rendering
- You need better font rendering for international text
Note: This function requires node-canvas to be installed. It may have system dependencies depending on your operating system (Cairo, pixman).
| Parameter | Type | Required | Description |
|------------|---------------------|----------|-------------|
| pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) |
| outputDir| string | ✅ Yes | Directory where TIFF files are written. Created automatically if it does not exist. |
| options | ConversionOptions | No | Optional settings (see below) |
Throws Error if:
- node-canvas is not installed
- The PDF file does not exist or cannot be read
- The PDF is corrupt or has no pages
scaleis outside the valid range (0 < scale ≤ 10)- The output directory cannot be created
ConversionOptions
interface ConversionOptions {
scale?: number; // Default: 3.0
compression?: TiffCompression; // Default: 'lzw'
filePrefix?: string; // Default: 'page'
binarize?: boolean; // Default: false
}
type TiffCompression = 'none' | 'packbits' | 'lzw';| Option | Type | Default | Description |
|---------------|-------------------|------------|-------------|
| scale | number | 3.0 | Render scale multiplier. 1.0 = 72 DPI (PDF native), 2.0 = 144 DPI, 3.0 ≈ 216 DPI (default), 4.17 ≈ 300 DPI. Valid range: (0, 10]. |
| compression | TiffCompression | 'lzw' | TIFF compression algorithm. See Compression Modes. |
| filePrefix | string | 'page' | Output filename prefix. Single-page PDFs: files are named ${prefix}.tiff (no page number). Multi-page PDFs: files are named ${prefix}-${pageNumber}.tiff. |
| binarize | boolean | false | When true, converts each page to 1-bit black-and-white using Otsu's adaptive threshold before encoding. Eliminates the anti-aliased gray fringe that pureimage adds to barcode edges, making barcodes scannable by hardware readers and fax systems. Output IFD: BitsPerSample=1, PhotometricInterpretation=0 (WhiteIsZero). |
ConversionResult
interface ConversionResult {
success: boolean; // true if ALL pages converted successfully
totalPages: number; // total pages in the PDF
convertedPages: number; // pages that were successfully written
outputFiles: string[]; // absolute paths to each TIFF file, in page order
error?: string; // set if success is false
}Examples
Convert with custom DPI (~300 DPI)
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');
const result = await convertPdfToTiff('invoice.pdf', './tiff-output', {
scale: 4.17, // 4.17 × 72 DPI ≈ 300 DPI
compression: 'lzw',
filePrefix: 'invoice',
});
// Multi-page: → invoice-1.tiff, invoice-2.tiff, ...
// Single-page: → invoice.tiffOutput to current directory
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');
const result = await convertPdfToTiff('document.pdf', './', {
filePrefix: 'scan',
});
console.log(result.outputFiles);
// Single-page: → ['scan.tiff']
// Multi-page: → ['scan-1.tiff', 'scan-2.tiff', ...]Uncompressed output (fastest, largest files)
const result = await convertPdfToTiff('scan.pdf', './raw', {
compression: 'none',
});PackBits compression (fast, moderate size)
const result = await convertPdfToTiff('report.pdf', './compressed', {
compression: 'packbits',
});High-fidelity conversion with embedded images (node-canvas)
Use convertPdfToTiffHighFidelity() when your PDFs contain embedded images, complex graphics, or need pixel-perfect rendering:
const { convertPdfToTiffHighFidelity } = require('pdf-to-tiff-pure-aloka');
const result = await convertPdfToTiffHighFidelity('document-with-images.pdf', './output', {
scale: 3.0,
compression: 'lzw',
filePrefix: 'page',
});TypeScript:
import { convertPdfToTiffHighFidelity } from 'pdf-to-tiff-pure-aloka';
const result = await convertPdfToTiffHighFidelity('catalog.pdf', './output', {
scale: 4.17, // ~300 DPI for high quality
compression: 'lzw',
});Barcode / fax-quality output (1-bit black-and-white)
Use binarize: true when the PDF contains barcodes, QR codes, or must be sent to a fax system. The canvas renderer anti-aliases barcode edges, producing gray pixels that can confuse fixed-threshold hardware readers. Enabling binarization applies Otsu's adaptive threshold to remove all gray, writing a compact 1-bit TIFF instead of an 8-bit RGB one.
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');
const result = await convertPdfToTiff('barcode-invoice.pdf', './output', {
scale: 3.0, // higher scale = more barcode detail
compression: 'lzw',
binarize: true, // → 1-bit B&W TIFF, Otsu adaptive threshold
});TypeScript:
import { convertPdfToTiff, ConversionOptions } from 'pdf-to-tiff-pure-aloka';
const options: ConversionOptions = {
scale: 3.0,
compression: 'lzw',
binarize: true,
};
const result = await convertPdfToTiff('barcode.pdf', './output', options);
// Output TIFF: BitsPerSample=1, PhotometricInterpretation=0 (WhiteIsZero)Tip: For documents that mix barcodes with full-colour content (logos, photos), leave
binarize: false(default) and use a separate post-processing step for the pages that need scanning.
Error handling
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');
try {
const result = await convertPdfToTiff('document.pdf', './output');
if (!result.success) {
// Some pages failed (non-fatal per-page errors)
console.warn(`Warning: ${result.error}`);
console.log(`Converted ${result.convertedPages}/${result.totalPages} pages`);
}
result.outputFiles.forEach(file => {
console.log('Created:', file);
});
} catch (err) {
// Fatal error: file not found, corrupt PDF, invalid options
console.error('Fatal error:', err.message);
}Check output file sizes
const fs = require('fs');
const { convertPdfToTiff } = require('pdf-to-tiff-pure-aloka');
const result = await convertPdfToTiff('document.pdf', './output', {
compression: 'lzw',
});
result.outputFiles.forEach(file => {
const size = fs.statSync(file).size;
console.log(`${file} — ${(size / 1024).toFixed(1)} KB`);
});Extract text from a PDF
const { convertPdfToText } = require('pdf-to-tiff-pure-aloka');
const text = await convertPdfToText('document.pdf');
console.log(text);
// Output: full text of all pages, pages separated by \n\nTypeScript:
import { convertPdfToText } from 'pdf-to-tiff-pure-aloka';
const text: string = await convertPdfToText('invoice.pdf');
if (text.trim().length > 0) {
console.log('Extracted text:', text);
} else {
console.log('No text found (image-only or encrypted PDF)');
}Compression Modes
| Mode | TIFF Tag | File Size | Encoding Speed | Best For |
|------------|----------|---------------|----------------|----------|
| none | 1 | Largest | Fastest | Debugging, further processing |
| packbits | 32773 | Moderate | Fast | General purpose |
| lzw | 5 | Smallest | Moderate | Storage, archival (default) |
Tip: For text-heavy or white-space-heavy documents, LZW achieves the best compression ratio. For photos or complex vector art, the difference between modes is smaller.
convertPdfToText()
convertPdfToText(pdfPath: string): Promise<string>Extracts all text content from a PDF file and returns it as a plain string.
| Parameter | Type | Required | Description |
|-----------|----------|----------|-------------|
| pdfPath | string | ✅ Yes | Path to the source PDF file (absolute or relative) |
Returns a Promise<string> — concatenated text of all pages, with pages separated by \n\n.
Returns an empty string if the PDF contains no extractable text (image-only or rasterized content).
Throws Error if:
- The PDF file does not exist or cannot be read
- The PDF is corrupt or has no pages
Note: Text extraction works on PDFs with embedded text streams. Scanned PDFs (images only) will return an empty string — use
convertPdfToTiffto get image output and apply OCR separately if needed.
Known Limitations
| Limitation | Details |
|------------|---------|
| Performance | Rendering is 3–10× slower than system-library solutions (Ghostscript, Poppler) because everything runs in JavaScript. Expect ~1–5 seconds per page depending on complexity. |
| Font rendering | PDFs that use unembedded proprietary fonts (e.g. old Vietnamese TCVN3 fonts) may render as empty boxes. Standard fonts (Helvetica, Times, Courier) require the standardFontDataUrl option of pdfjs-dist; this package uses best-effort fallback only. |
| Color accuracy | Complex color spaces (CMYK, ICC profiles) are handled by pdfjs on a best-effort basis. Slight color shifts are possible. |
| Memory usage | Very high-resolution renders (scale > 4.0) of large pages can use significant RAM. Process pages sequentially for large documents. |
| No multi-page TIFF | Each page produces a separate .tiff file. Multi-page (strips) TIFF is not supported. || Binarize on mixed pages | binarize: true applies a single global Otsu threshold to the whole page. Pages with both full-colour photos and barcodes may lose colour detail. Use binarize: false (default) for colour output. |
License
MIT © pdf-to-tiff-pure-aloka contributors
