# Image to PDF & PDF to Image Converter – JPG, PNG, WebP (`gazidev/pdf-image-converter`) Actor

Convert images to PDF (JPG, PNG, WebP, HEIC, TIFF, GIF; one combined PDF, one per image or named groups; A4, Letter or fit-to-image; margins; compression) and PDF to images (PNG, JPG, WebP at any DPI, page ranges, ZIP, thumbnails). $2 per 1,000 pages.

- **URL**: https://apify.com/gazidev/pdf-image-converter.md
- **Developed by:** [Cemal Atakli](https://apify.com/gazidev) (community)
- **Categories:** Automation, Developer tools
- **Stats:** 1 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 pdf page rendereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Image to PDF & PDF to Image Converter – JPG, PNG, WebP

Convert **images to PDF** and **PDF to images** in bulk, from URLs, with one API call:

- **Images to PDF (JPG to PDF, PNG to PDF, WebP/HEIC to PDF):** combine many images into **one PDF**, make **one PDF per image**, or build several **named PDFs** in one run. A4, US Letter, Legal, A3, A5 or *fit to image*, automatic portrait/landscape, margins, and compression options. JPG photos are embedded **byte-for-byte (no quality loss)**.
- **PDF to images (PDF to JPG, PDF to PNG, PDF to WebP):** render every page, or a page range, at the DPI you choose (default 150). Optional **ZIP per PDF** and **thumbnail mode** (first page only).

Every output file is saved with a **public download link**, and you get one dataset row per PDF created or per page rendered. There is no browser and no proxy, so it is fast and cheap: **$0.002 per page** in either direction, plus $0.001 per PDF created.

### What it does

- **Image to PDF converter:** accepts JPG/JPEG, PNG, WebP, HEIC/HEIF (iPhone photos), AVIF, TIFF, BMP and GIF (first frame). Images go into the PDF in the order you list them.
- **Three output modes:** one combined PDF (default), one PDF per image (batch JPG to PDF), or `pdfGroups`, where each named group of image URLs becomes its own PDF, e.g. one PDF per invoice, order or customer.
- **Page layout:** A4, Letter, Legal, A3, A5, or *fit to image* (the page has exactly the size of the image). The orientation is automatic (landscape pages for wide images) or forced. Margins are in millimetres. Each image is scaled to fit and centred, keeping its aspect ratio. EXIF rotation from phone photos is applied.
- **Compression:** `auto` keeps JPGs unchanged, keeps PNG/GIF/TIFF lossless and stores WebP/HEIC/AVIF as JPG. `jpeg` makes the smallest PDF by re-encoding everything at your `quality`. `lossless` means no quality loss at all. You can also downscale big photos (`maxImageSize`, e.g. 2000 px) to shrink the PDF about 4×. Transparent images get a white (or custom) background.
- **PDF to image converter:** uses Google's PDFium engine (the same engine Chrome uses), so fonts, vector graphics, form fields and annotations render correctly. Output is PNG (sharpest for text), JPG or WebP (smallest), at 36–600 DPI, with an optional grayscale mode.
- **Page ranges:** `1-5`, `1,3,10-`, or `-3--1` for the last three pages. You only pay for pages rendered.
- **ZIP per PDF:** all page images of a PDF in one ZIP, free. Every page row contains the `zipUrl`.
- **Thumbnails:** the first page at a fixed width (default 400 px) for previews, catalogues and document libraries.
- **Password-protected PDFs** open with `pdfPassword`.
- **Share links work:** Google Drive, Dropbox and GitHub `blob` links (and arXiv `/abs/` pages) are turned into direct downloads.
- **Robust:** downloads are retried with backoff (honouring `Retry-After`), and there is a file size limit. Each failure becomes a **free** error row with a clear `errorCode`, and the run carries on. Codes include `http-404`, `not-an-image`, `is-a-pdf`, `not-a-pdf`, `invalid-pdf`, `password-required`, `wrong-password`, `too-large`, `invalid-url` and `invalid-page-range`.

### Use cases

- **Receipts, invoices and delivery photos to PDF:** merge the photos of each order into one PDF per order with `pdfGroups`, ready for accounting or e-mail.
- **Scanned pages and phone photos (HEIC) to PDF:** make a multi-page A4 document from page photos.
- **E-commerce and real estate:** product or property photo sets as PDF catalogues or brochures.
- **PDF to JPG/PNG for the web:** show PDF pages as images in a CMS, shop, blog, or social post.
- **PDF thumbnails:** cover images for document libraries, search results, LMS courses and Notion/Airtable records.
- **OCR and AI pipelines:** render PDF pages at 300 DPI for OCR engines or vision LLMs (GPT-4o, Claude, Gemini) that take images.
- **Automation:** Make, Zapier, n8n or a webhook sends URLs and gets download links back.

### Input example: images to PDF

```json
{
  "operation": "images-to-pdf",
  "imageUrls": [
    "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/gps/DSCN0010.jpg",
    "https://www.gstatic.com/webp/gallery/1.webp",
    "https://raw.githubusercontent.com/xinntao/Real-ESRGAN/master/inputs/children-alpha.png"
  ],
  "pdfMode": "combine",
  "outputFileName": "holiday-photos",
  "pageSize": "A4",
  "orientation": "auto",
  "marginMm": 10,
  "imageCompression": "auto"
}
```

Several PDFs in one run:

```json
{
  "operation": "images-to-pdf",
  "pdfGroups": [
    { "name": "order-1042", "imageUrls": ["https://example.com/1042-a.jpg", "https://example.com/1042-b.heic"] },
    { "name": "order-1043", "imageUrls": ["https://example.com/1043.png"] }
  ],
  "pageSize": "Letter"
}
```

### Input example: PDF to images

```json
{
  "operation": "pdf-to-images",
  "pdfUrls": ["https://www.irs.gov/pub/irs-pdf/fw9.pdf"],
  "imageFormat": "png",
  "dpi": 150,
  "pageRange": "1-2",
  "createZip": true
}
```

If you click **Start** with an empty input, a small demo runs (3 sample images → 1 A4 PDF), so you can see the output right away.

### Output example

One row per PDF created:

```json
{
  "type": "pdf",
  "status": "ok",
  "fileName": "holiday-photos.pdf",
  "pdfUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/001-holiday-photos.pdf",
  "pageCount": 3,
  "pdfBytes": 440995,
  "imagesRequested": 4,
  "imagesFailed": 1,
  "pageSize": "A4",
  "orientation": "auto",
  "marginMm": 10,
  "imageCompression": "auto",
  "images": [
    { "url": "https://…/DSCN0010.jpg", "sourceFormat": "jpg", "width": 640, "height": 480, "embeddedAs": "jpg (original, lossless pass-through)" },
    { "url": "https://…/1.webp", "sourceFormat": "webp", "width": 550, "height": 368, "embeddedAs": "jpg (q85)" }
  ]
}
```

One row per page rendered:

```json
{
  "type": "page",
  "status": "ok",
  "pdfUrl": "https://www.irs.gov/pub/irs-pdf/fw9.pdf",
  "fileName": "fw9.pdf",
  "page": 1,
  "pageCount": 6,
  "imageUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/001-fw9-page-0001.png",
  "format": "png",
  "width": 1275,
  "height": 1650,
  "dpi": 150,
  "bytes": 551997,
  "zipUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/001-fw9-pages.zip",
  "pdfTitle": "Form W-9 (Rev. March 2024)"
}
```

Failures appear as free rows with `"type": "error"`, an `errorCode` and a readable `error`. A `SUMMARY` record in the key-value store holds the run totals. The Output tab has separate views for **PDFs**, **Page images** and **Errors**.

### Pricing

Pay only for results. Errors, skipped images, ZIPs and the summary are free.

| Event | Price |
|---|---|
| Page added to a PDF (`image-page`) | $0.002 |
| PDF created (`pdf-created`) | $0.001 |
| PDF page rendered to an image (`page-rendered`; pages above 10 megapixels, e.g. 600 DPI, count once per started 10 MP) | $0.002 |
| Actor start | $0.00005 |

Examples: 1 image → 1 PDF = $0.003. 10 photos → 1 PDF = $0.021. A 100-page PDF → 100 PNGs = $0.20.

How it compares (Apify Store, October 2026):

| Actor | Images to PDF | PDF to images | ZIP |
|---|---|---|---|
| **This Actor** | $0.002 / page + $0.001 / PDF | **$0.002 / page** | free |
| akash9078/image-pdf-converter | $0.005 / converted file | $0.005 / page | – |
| hipersoft/images-to-pdf | $0.005 / PDF | – | – |
| programmersoham/pdf-to-jpg-converter | – | $0.005 / page | $0.05 |

Set **Maximum cost per run** in the run options. The Actor stops cleanly when the limit is reached, keeps everything already created, and marks a cut-off PDF as `partial`.

### FAQ

**Does converting JPG to PDF reduce quality?** No. With the default `auto` compression, JPG files are embedded unchanged (lossless pass-through), so the PDF is about the size of the photos. Choose `jpeg` with a lower `quality` or set `maxImageSize` when you need a smaller PDF.

**Can I convert iPhone HEIC photos to PDF?** Yes. HEIC/HEIF, AVIF and WebP are decoded and stored as high-quality JPG inside the PDF.

**How do I get one PDF per image?** Set `pdfMode` to `per-image`. To get one PDF per order or customer, use `pdfGroups`.

**Which DPI should I use for PDF to image?** 72 for small previews, 150 (the default) for screens and the web, 300 for print and OCR. PNG is the sharpest for text, JPG suits photos, and WebP gives the smallest files.

**How do I download all page images at once?** Turn on `createZip`. Each PDF gets a free ZIP, and its link is in every page row (`zipUrl`). You can also find every file under *Storage → Key-value store*.

**My PDF is password-protected.** Set `pdfPassword`. Without it the row reports `password-required`, and you are not charged.

**How many images can go into one PDF?** Hundreds. All images of one PDF are held in memory while the PDF is built, so for more than about 150 large phone photos in a single PDF, use 2–4 GB memory or set `maxImageSize`.

**How long are the files kept?** As long as the run's storage is kept on your Apify account (unnamed storages expire with your plan's data retention period). Download or copy them to your own storage if you need them for longer.

**Can it extract the text of a PDF?** This Actor converts files. For text or Markdown, use our *PDF to Text & Markdown* Actor (gazidev/pdf-text-extractor).

### Use with AI agents / Apify MCP

The Actor works as a tool for AI agents through the [Apify MCP server](https://mcp.apify.com) (Claude, Cursor, ChatGPT, LangChain, n8n AI agents). An agent can call `gazidev/pdf-image-converter` with `{"operation": "pdf-to-images", "pdfUrls": [...], "dpi": 150}` to "see" PDF pages as images, or with `{"imageUrls": [...]}` to turn screenshots or photos into a shareable PDF link. The inputs are small and flat, and the outputs are plain JSON with download URLs, which makes it easy for LLMs to use.

API example (synchronous run, returns the dataset items):

```bash
curl -X POST "https://api.apify.com/v2/acts/gazidev~pdf-image-converter/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"operation":"pdf-to-images","pdfUrls":["https://www.irs.gov/pub/irs-pdf/fw9.pdf"],"imageFormat":"jpg","pageRange":"1"}'
```

### Notes

- Only process files you have the right to use. The Actor downloads the URLs you give it and nothing else.
- Built with img2pdf, pikepdf, PDFium (pypdfium2), Pillow and pillow-heif.

# Actor input Schema

## `operation` (type: `string`):

Images to PDF uses the 'Images to PDF' section below; PDF to images uses the 'PDF to images' section.

## `imageUrls` (type: `array`):

Direct links to JPG, PNG, WebP, HEIC/HEIF, AVIF, TIFF, BMP or GIF (first frame) files, in page order. Google Drive, Dropbox and GitHub share links work. Failed images are skipped and reported for free.

## `pdfMode` (type: `string`):

Ignored when 'PDF groups' is used (each group becomes one PDF).

## `pdfGroups` (type: `array`):

Make several named PDFs in one run, e.g. \[{"name": "invoice-1042", "imageUrls": \["https://…/p1.jpg", "https://…/p2.jpg"]}, {"name": "receipts-may", "imageUrls": \["…"]}]. When set, 'Image URLs' is ignored.

## `outputFileName` (type: `string`):

Without .pdf. Letters, digits, '-', '\_' and '.' are kept.

## `pageSize` (type: `string`):

Images are scaled to fit inside the page margins and centered, keeping their aspect ratio.

## `orientation` (type: `string`):

Not used with 'Fit to image'.

## `marginMm` (type: `integer`):

White border around each image. 0 = edge to edge.

## `imageCompression` (type: `string`):

Auto never re-compresses JPG photos, so there is no quality loss and the PDF is about the size of the photos.

## `maxImageSize` (type: `integer`):

E.g. 2000 makes 12-megapixel phone photos about 4× smaller in the PDF (still sharp on A4 at 170+ DPI). 0 = keep original size.

## `backgroundColor` (type: `string`):

Hex colour used under transparent PNG/WebP areas.

## `maxImages` (type: `integer`):

Use only the first N image URLs. 0 = no limit.

## `pdfUrls` (type: `array`):

Direct links to PDF files. Google Drive, Dropbox, GitHub and arXiv links work. Used when 'What do you want to do?' is 'PDF to images'.

## `imageFormat` (type: `string`):

Output format for pdf-to-images. PNG keeps text sharpest, JPG is smaller for photos, WebP is the smallest.

## `dpi` (type: `integer`):

72 = screen preview, 150 = good default (1275×1650 px for a Letter page), 300 = print/OCR quality. Pages above 10 megapixels (e.g. 600 DPI) count as one page per started 10 MP.

## `pageRange` (type: `string`):

Empty = all pages. Examples: '1-5', '1,3,10-', '-3--1' (last 3 pages).

## `thumbnailsOnly` (type: `boolean`):

Render only page 1 of each PDF at 'Thumbnail width' – for previews and catalogues.

## `thumbnailWidth` (type: `integer`):

Width in pixels of the first-page thumbnail when thumbnail mode is on. Height keeps the page aspect ratio.

## `createZip` (type: `boolean`):

All page images of a PDF in one ZIP (free). Every page row gets a zipUrl.

## `grayscale` (type: `boolean`):

Render pages (pdf-to-images) in grayscale. Smaller files for scanned documents.

## `pdfPassword` (type: `string`):

For password-protected PDFs (the same password is tried for every PDF).

## `maxPagesPerPdf` (type: `integer`):

0 = no limit.

## `maxPdfs` (type: `integer`):

0 = no limit.

## `quality` (type: `integer`):

Used for JPG/WebP page images and for images re-encoded into PDFs.

## `maxFileSizeMb` (type: `integer`):

Larger files are skipped for free.

## `maxConcurrency` (type: `integer`):

How many files are downloaded and processed in parallel. Lower it for very large files or low memory.

## `proxyConfiguration` (type: `object`):

Only needed if a file host blocks datacenter IPs.

## Actor input object example

```json
{
  "operation": "images-to-pdf",
  "imageUrls": [
    "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/gps/DSCN0010.jpg",
    "https://www.gstatic.com/webp/gallery/1.webp",
    "https://raw.githubusercontent.com/xinntao/Real-ESRGAN/master/inputs/children-alpha.png"
  ],
  "pdfMode": "combine",
  "pdfGroups": [],
  "outputFileName": "images",
  "pageSize": "A4",
  "orientation": "auto",
  "marginMm": 10,
  "imageCompression": "auto",
  "maxImageSize": 0,
  "backgroundColor": "#ffffff",
  "maxImages": 0,
  "pdfUrls": [
    "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
  ],
  "imageFormat": "png",
  "dpi": 150,
  "thumbnailsOnly": false,
  "thumbnailWidth": 400,
  "createZip": false,
  "grayscale": false,
  "maxPagesPerPdf": 0,
  "maxPdfs": 0,
  "quality": 85,
  "maxFileSizeMb": 100,
  "maxConcurrency": 6
}
```

# Actor output Schema

## `pdfs` (type: `string`):

No description

## `pages` (type: `string`):

No description

## `errors` (type: `string`):

No description

## `files` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "operation": "images-to-pdf",
    "imageUrls": [
        "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/gps/DSCN0010.jpg",
        "https://www.gstatic.com/webp/gallery/1.webp",
        "https://raw.githubusercontent.com/xinntao/Real-ESRGAN/master/inputs/children-alpha.png"
    ],
    "pdfMode": "combine",
    "outputFileName": "images",
    "pageSize": "A4",
    "marginMm": 10,
    "pdfUrls": [
        "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
    ],
    "imageFormat": "png",
    "dpi": 150
};

// Run the Actor and wait for it to finish
const run = await client.actor("gazidev/pdf-image-converter").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "operation": "images-to-pdf",
    "imageUrls": [
        "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/gps/DSCN0010.jpg",
        "https://www.gstatic.com/webp/gallery/1.webp",
        "https://raw.githubusercontent.com/xinntao/Real-ESRGAN/master/inputs/children-alpha.png",
    ],
    "pdfMode": "combine",
    "outputFileName": "images",
    "pageSize": "A4",
    "marginMm": 10,
    "pdfUrls": ["https://www.irs.gov/pub/irs-pdf/fw9.pdf"],
    "imageFormat": "png",
    "dpi": 150,
}

# Run the Actor and wait for it to finish
run = client.actor("gazidev/pdf-image-converter").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "operation": "images-to-pdf",
  "imageUrls": [
    "https://raw.githubusercontent.com/ianare/exif-samples/master/jpg/gps/DSCN0010.jpg",
    "https://www.gstatic.com/webp/gallery/1.webp",
    "https://raw.githubusercontent.com/xinntao/Real-ESRGAN/master/inputs/children-alpha.png"
  ],
  "pdfMode": "combine",
  "outputFileName": "images",
  "pageSize": "A4",
  "marginMm": 10,
  "pdfUrls": [
    "https://www.irs.gov/pub/irs-pdf/fw9.pdf"
  ],
  "imageFormat": "png",
  "dpi": 150
}' |
apify call gazidev/pdf-image-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,gazidev/pdf-image-converter"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4I6SqoZcRueZEI9zZ/builds/iYYbKQM0yZ7VZymIh/openapi.json
