DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
JavaScript

How to Convert a PDF to Images in Node.js

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use PDF.js to render each PDF page into a Node.js canvas, then write that canvas as PNG, JPEG or another supported raster format. The essential sequence is getDocument() → getPage() → getViewport() → page.render() → canvas.toBuffer(). The viewport scale determines the output dimensions.

This guide gives you a complete Node.js implementation, target-width and page-range controls, operational limits for large files, troubleshooting, and a comparison with higher-level packages.

Choose the right conversion layer

A PDF is normally a collection of vector drawing instructions, text and embedded images. Converting it to an image means rasterizing one page at a time onto a pixel surface. Your choice is mainly about control versus setup:

Approach What it gives you What you must verify
PDF.js directly Explicit document loading, page selection, viewport sizing and render parameters. Canvas implementation, fonts, worker or asset configuration, image encoding and Node.js runtime compatibility.
pdf-to-img A higher-level API that yields page images and exposes page selection and scale options. Current README, supported Node.js versions, output type and resource lifecycle.
pdf2pic Page conversion to image, base64 or buffer with page-selection controls. GraphicsMagick/ImageMagick installation, deployment requirements and current runtime support.

Use PDF.js when you need predictable dimensions, custom render settings or per-page control. A wrapper can reduce code, but check its current dependencies before deploying; available package descriptions do not establish a benchmark, maintenance advantage or complete compatibility matrix.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Epson Workforce ES-50 Compact & Lightweight Mobile Document Scanner
  • PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
  • QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
  • VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
  • INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
  • EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0

Install the Node.js dependencies

Create a project using an actively supported Node.js release, then install PDF.js and a canvas implementation:

npm init -y
npm install pdfjs-dist canvas

The canvas package contains native components. On some Linux distributions you may need the platform’s Cairo, Pango and related development libraries before npm install canvas can compile. In a container, install those libraries in the image rather than at application start.

Use an ES module file (for example, convert.mjs). The pdfjs-dist/legacy/build/pdf.mjs entry point is appropriate for a Node process and avoids browser-only assumptions.

Complete Node.js converter

The following program converts selected pages or every page, optionally targeting a pixel width. It renders pages sequentially so one canvas is never asked to draw two pages at once.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import fs from 'node:fs/promises';
import path from 'node:path';
import { createCanvas } from 'canvas';
import { getDocument } from 'pdfjs-dist/legacy/build/pdf.mjs';

class NodeCanvasFactory {
  create(width, height) {
    const canvas = createCanvas(Math.ceil(width), Math.ceil(height));
    return { canvas, context: canvas.getContext('2d') };
  }

  reset(canvasAndContext, width, height) {
    canvasAndContext.canvas.width = Math.ceil(width);
    canvasAndContext.canvas.height = Math.ceil(height);
  }

  destroy(canvasAndContext) {
    canvasAndContext.canvas.width = 0;
    canvasAndContext.canvas.height = 0;
    canvasAndContext.canvas = null;
    canvasAndContext.context = null;
  }
}

function parsePages(value, pageCount) {
  if (!value || value === 'all') {
    return Array.from({ length: pageCount }, (_, i) => i + 1);
  }
  const pages = new Set();
  for (const part of value.split(',')) {
    if (part.includes('-')) {
      const [first, last] = part.split('-').map(Number);
      if (!Number.isInteger(first) || !Number.isInteger(last) || first < 1 || last < first) {
        throw new Error(`Invalid page range: ${part}`);
      }
      for (let page = first; page <= last; page++) pages.add(page);
    } else {
      const page = Number(part);
      if (!Number.isInteger(page) || page < 1) throw new Error(`Invalid page number: ${part}`);
      pages.add(page);
    }
  }
  return [...pages].sort((a, b) => a - b).filter(page => page <= pageCount);
}

function parseArgs(args) {
  const [inputPath, ...rest] = args;
  if (!inputPath) throw new Error('Usage: node convert.mjs input.pdf [--out out-dir] [--pages 1,3-5] [--width 1800] [--scale 2] [--format png|jpeg]');
  const options = { inputPath, outDir: 'images', pages: 'all', width: null, scale: 1, format: 'png' };
  for (let i = 0; i < rest.length; i++) {
    const arg = rest[i];
    const next = rest[++i];
    if (arg === '--out') options.outDir = next;
    else if (arg === '--pages') options.pages = next;
    else if (arg === '--width') options.width = Number(next);
    else if (arg === '--scale') options.scale = Number(next);
    else if (arg === '--format') options.format = next.toLowerCase();
    else throw new Error(`Unknown option: ${arg}`);
  }
  if (!['png', 'jpeg'].includes(options.format)) throw new Error('--format must be png or jpeg');
  if (options.width !== null && (!Number.isFinite(options.width) || options.width <= 0)) throw new Error('--width must be a positive number');
  if (!Number.isFinite(options.scale) || options.scale <= 0) throw new Error('--scale must be positive');
  return options;
}

async function convert(options) {
  const data = new Uint8Array(await fs.readFile(options.inputPath));
  const loadingTask = getDocument({ data, disableFontFace: true });
  const pdf = await loadingTask.promise;
  const pages = parsePages(options.pages, pdf.numPages);
  if (pages.length === 0) throw new Error('No page numbers matched the document');
  await fs.mkdir(options.outDir, { recursive: true });
  const canvasFactory = new NodeCanvasFactory();

  try {
    for (const pageNumber of pages) {
      const page = await pdf.getPage(pageNumber);
      const baseViewport = page.getViewport({ scale: 1 });
      const scale = options.width ? options.width / baseViewport.width : options.scale;
      const viewport = page.getViewport({ scale });
      const surface = canvasFactory.create(viewport.width, viewport.height);
      try {
        await page.render({
          canvasContext: surface.context,
          viewport,
          canvasFactory
        }).promise;
        const extension = options.format === 'jpeg' ? 'jpg' : 'png';
        const buffer = options.format === 'jpeg'
          ? surface.canvas.toBuffer('image/jpeg', { quality: 0.92 })
          : surface.canvas.toBuffer('image/png');
        const filename = `page-${String(pageNumber).padStart(4, '0')}.${extension}`;
        await fs.writeFile(path.join(options.outDir, filename), buffer);
        console.log(`${filename}: ${Math.ceil(viewport.width)}x${Math.ceil(viewport.height)}`);
      } finally {
        canvasFactory.destroy(surface);
      }
      page.cleanup();
    }
  } finally {
    await pdf.destroy();
  }
}

try {
  await convert(parseArgs(process.argv.slice(2)));
} catch (error) {
  console.error(error.message);
  process.exitCode = 1;
}

Run it like this:

node convert.mjs invoice.pdf --out rendered --pages 1,3-4 --width 1800 --format png
node convert.mjs handbook.pdf --scale 2 --format jpeg

The first command creates only pages 1, 3 and 4 at a width of about 1,800 pixels. The second uses twice the PDF's scale-1 dimensions and writes JPEG files.

How the rendering pipeline works

Load bytes or a file

getDocument({ data }) accepts the PDF bytes as a Uint8Array. Its loading task resolves to a document object. For a server-side file, reading bytes avoids browser origin rules. If you load a URL instead, normal Fetch or XHR behavior applies: the remote server must permit the request with appropriate same-origin or CORS headers.

Rank #2
Sale
Brother DS-640 Compact Mobile Document Scanner, (Model: DS640)
  • FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
  • ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
  • READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
  • WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
  • OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)

Select a page

pdf.getPage(pageNumber) is one-based. The example parses individual numbers and inclusive ranges, removes duplicates and ignores numbers beyond the document's page count. You can replace that policy with strict rejection if silently skipping an out-of-range page would be unsafe for your workflow.

Choose dimensions with a viewport

A scale of 1 returns the page's base dimensions. To target a width, calculate scale = desiredWidth / baseViewport.width, then request a second viewport at that scale. The canvas must be allocated to the resulting viewport width and height before rendering. Height follows the page's aspect ratio.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Render and encode

page.render() returns a render task; await its promise before reusing the canvas. PNG is lossless and suited to text, diagrams and transparency. JPEG is smaller for photographic pages but introduces lossy compression; the sample uses quality 0.92. Add WebP only after confirming that your installed canvas build supports WebP encoding.

Resolution, page ranges and memory

Scale versus DPI

PDF.js controls output through viewport scale rather than a DPI flag. If you know the desired pixel width, use the width option because it produces a deterministic result across pages with different PDF sizes. A larger scale increases both dimensions and therefore memory roughly with the number of pixels.

Render sequentially

Keep one page in flight per canvas unless you have measured a bounded-concurrency design. Rendering many large pages simultaneously can multiply native and JavaScript memory. The sample destroys each canvas and calls page.cleanup() before continuing, then destroys the document at the end.

Set operational limits

For untrusted or unusually large PDFs, enforce a maximum file size, page count, target width and total pixel budget before rendering. PDF.js exposes a maxImageSize configuration for limiting very large images; choose a value appropriate to your service rather than assuming an unlimited default is safe. Reject work that exceeds your process memory budget and run conversion in an isolated worker or job process when inputs are user supplied.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
  • STAY ORGANIZED – Easily convert your paper documents into digital formats like searchable PDF files, JPEGs, and more.Power Consumption : 2.5W or less (Energy Saving Mode: 0.7W). Suggested Daily Volume : 500 scans..Does it contain liquid: no
  • CONVENIENT AND PORTABLE –lightweight and small in size, you can take the scanner anywhere from home offices, classrooms, remote offices, and anywhere in between
  • HANDLES VARIOUS MEDIA TYPES – Digitize receipts, business cards, plastic or embossed cards, reports, legal documents, and more
  • FAST AND EFFICIENT – No technical hurdles or complicated setups here; easily scan both sides of a document at the same time, in color or black-and-white, at up to 12 pages-per-minute, and with a 20 sheet automatic feeder
  • BROAD COMPATIBILITY – Works with both Windows and Mac devices, be it laptop or computer

Node.js-specific configuration

Node defaults differ from browser defaults. In the API reference, disableFontFace defaults to true in Node.js; OffscreenCanvas and ImageDecoder support default to false, and maxImageSize has no pixel limit unless you set one. Font fallback, standard-font assets, CMaps, wasm files, workers and canvas factories can all affect fidelity. If text appears substituted or missing, verify the font and asset configuration for the exact PDF.js build you installed.

The custom canvas factory in the example gives PDF.js explicit creation, reset and destruction hooks. Keep those hooks if you process many pages, because releasing native canvas surfaces is as important as releasing JavaScript references.

Higher-level package alternatives

pdf-to-img

Search results describe an API that yields page images and supports page selection and scale. It can be convenient when you do not need direct render parameters. Confirm its current Node.js support, output representation and how it closes or disposes resources before adopting it.

pdf2pic

Search results describe conversion to image, base64 or buffer and page selection. Its deployment may require GraphicsMagick or ImageMagick. Verify those binaries, permissions and runtime compatibility in the same environment where your application will run.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Neither package should be called faster, more compatible or better maintained without current documentation or your own test. Compare abstraction level, page selection, dimensions, image formats, native dependencies and failure behavior against the direct PDF.js approach.

Reliability and production checklist

  • Validate that the input is a PDF and impose file-size and page-count limits.
  • Use a temporary output directory and atomically publish completed files so consumers never see half a page.
  • Assign a timeout to the job and terminate a worker that exceeds your memory or time budget.
  • Log input identity, page number, viewport dimensions, format and elapsed time; do not log sensitive document contents.
  • Keep pages sequential unless controlled concurrency has been measured under your workload.
  • Test PDFs containing embedded fonts, transparency, very large images, rotated pages, annotations and encrypted content.
  • Pin and review dependency versions; native canvas upgrades can change installation requirements.

Troubleshooting

Cannot find module 'canvas' or installation failures

Install the package in the same project and check that your Node.js version is supported. On Linux, install the Cairo/Pango development libraries required by your distribution, then reinstall canvas. In minimal containers, use an image that includes those native libraries.

Rank #4
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
  • IRIScan Express, portable scanner : scans color and black and white documents a blazing speed up to 8ppm simplex. Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
  • IRIScan Express mobile scanner is powered via an included micro USB 2. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan. USB cable provided. AC Adapter not provided and not needed.
  • IRIScan flatbed scanner uses a simplex scanning mode allows for quick and straightforward scanning of single-sided documents. IRIScan with its full portable features is the ideal document scanners for computers.
  • IRIScan document scanner : Versatile scanning capabilities, including scanning to Word, PDF, and Excel formats with companion software provided Readiris OCR
  • Receipt scanner and card scanner with Additional features include scanning business cards directly to Outlook, photo scanning, and receipt scanning for efficient document management

Fonts look wrong or text is missing

Node disables browser font-face behavior by default. Check the PDF.js font and standard-font configuration, provide required assets, and test with the actual documents that fail. Do not assume a browser's installed fonts are available in a server container.

Output is blank or the render promise rejects

Make sure the canvas dimensions are set from the requested viewport before calling page.render(), await the render task, and pass a real 2D context. Confirm that the page number is within pdf.numPages and that the PDF can be opened independently.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Process memory grows with every page

Render one page at a time, destroy the canvas surface, call page.cleanup(), and destroy the document after the batch. Lower the scale or target width, cap image dimensions with maxImageSize, and move untrusted jobs into a bounded worker process.

A remote URL cannot be loaded

Fetch the file on your server and pass its bytes when the remote host does not provide the required CORS headers. Check redirects, authentication and response content type; a web error page is not a valid PDF.

JPEG files are unexpectedly large or soft

JPEG quality and pixel dimensions both affect size. Reduce quality for photographic pages, but use PNG for crisp text and line art. If text is unreadable, increase the target width rather than only increasing JPEG quality.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your real input is a publicly reachable web page and you need a clean screenshot rather than rasterizing a local PDF, ScreenshotNeo provides a single HTTP request. Its cleanup steps accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups and chat widgets before capture; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. It is not a replacement for PDF.js when you must render local PDF bytes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the ScreenshotNeo documentation for parameters and response handling.

Best Value
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
  • Scanner type: Document
  • Connectivity technology: USB
  • With Auto Scan Mode, the scanner automatically detects what you're scanning
  • Digitize documents and images
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get('https://api.screenshotneo.com/v1/shot', params={'access_key': 'YOUR_API_KEY', 'url': 'https://example.com'}, timeout=90)
r.raise_for_status()
open('shot.webp', 'wb').write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
await Bun.write('shot.webp', res);

ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is included on every plan. Create a free ScreenshotNeo account to get started.

Frequently Asked Questions

Can I convert only selected PDF pages?

Yes. Pass a comma-separated list and inclusive ranges such as --pages 2,5-7; the sample sorts and deduplicates them before rendering.

Does this preserve selectable text?

No. The result is a raster image. Keep the original PDF when you need searchable or selectable text.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can PDF.js read an encrypted PDF?

Only when the document can be opened with the required password and configuration. Handle password prompts and rejected documents as explicit job errors rather than treating them as blank pages.

Should I use PNG or JPEG for scanned documents?

PNG is safer for text and diagrams. JPEG is often smaller for photographic scans, but its compression can soften small type.

Quick Recap

Bestseller No. 3
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
Canon imageFORMULA R10 - Portable Document Scanner, USB Powered, Duplex Scanning, Document Feeder, Easy Setup, Convenient, Perfect for Mobile Users, White
BROAD COMPATIBILITY – Works with both Windows and Mac devices, be it laptop or computer; This product is not intended for scanning photographs on photo paper / photographic media
$184.00
Bestseller No. 4
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
IRIScan Express 4 Black Compact Portable USB Simplex Document Scanner, 8 PPM for Contracts, Invoices and Business Cards, Compatible with Windows, Readiris PDF Included
Find our Software here : irislink.com/start; IRIScan Express is only compatible Windows platform and not macintosh
$129.00
Bestseller No. 5
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Scanner type: Document; Connectivity technology: USB; With Auto Scan Mode, the scanner automatically detects what you're scanning
$75.00

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.