JPG to PDF Converter - Photos and Scans avatar

JPG to PDF Converter - Photos and Scans

Under maintenance

Pricing

Pay per usage

Go to Apify Store
JPG to PDF Converter - Photos and Scans

JPG to PDF Converter - Photos and Scans

Under maintenance

Convert JPG to PDF online in seconds. Upload photos or scans, or paste URLs, and get one multi-page PDF - or a separate PDF per image. Also converts PNG, WebP, TIFF and HEIC. Up to 100 images per run, with page size, margin and quality control.

Pricing

Pay per usage

Rating

0.0

(0)

Developer

Marcel Rebro

Marcel Rebro

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Convert JPG to PDF online, along with PNG, HEIC, WebP, TIFF, BMP and GIF. Combine a folder of photos or scans into one multi-page PDF, or convert each image to its own PDF. Upload files or paste URLs, pick a page size, get the result back. No account or desktop software needed.

A PDF is what forms, ticketing systems and email attachments actually accept. Photographs of documents, receipts and passports arrive as JPG or HEIC, scanners produce one image per page, and phones produce a camera roll - none of which can be handed over as they are. This converter is the step in between: the images go in, one PDF comes out, and the pages are in the order you listed them.

  • 🖼️ Every common image format - .jpg, .jpeg, .png, .webp, .tiff, .bmp, .gif, plus .heic, .heif and .avif from iPhones and modern cameras
  • 📚 Many images, one PDF - list the files in the order you want them and each becomes a page
  • 🗂️ Or many images, many PDFs - turn off one switch and a batch comes back as a ZIP of separate PDFs
  • 📄 Page size that suits the job - one page per image at its own size, or a fixed A4, Letter or Legal sheet
  • 🔄 Turns each page the right way up - honours EXIF rotation and gives a landscape photo a landscape page
  • 🎚️ Quality you control - from small-and-lossy to fully lossless
  • 💸 Costs a fraction of a cent per PDF
  • 🔌 Runs from the API, a schedule or an integration - it is an Apify Actor, so Zapier, Make, n8n and MCP clients can call it

How to convert JPG to PDF

  1. Click Try for free and sign in to Apify.
  2. Upload your images in the Images field, or paste direct URLs to them. The order you list them in is the order of the pages.
  3. Leave Page size on auto, or choose a4, letter or legal if the PDF is going to be printed.
  4. Click Start.
  5. Download the PDF from the Storage tab, or from the download URL in the run's dataset record.

How to convert multiple JPG files into one PDF

That is the default. Put every image in the Images field, in page order, and the run produces one PDF with one page per image. Up to 100 images go into a single PDF, and mixing formats is fine - a run can hold JPGs from a phone, PNGs from a screenshot tool and TIFFs from a scanner at the same time.

Converting each image to its own PDF instead means one run per image, which costs more in container startup than it does in conversion. Combining is both cheaper and what most people want.

How to convert many JPG files into separate PDFs

The other thing "batch convert" can mean: 50 photos in, 50 PDFs out. Turn Combine into one PDF off. Every image is then converted on its own, each PDF is named after the image it came from, and the run hands back a ZIP of all of them - OUTPUT is the archive, and each PDF is also a record of its own in the Storage tab.

Two things behave better in this mode than you might expect. A file that cannot be converted costs only its own PDF: the batch carries on and that image's dataset record says why it failed, so one corrupt photo out of 50 does not throw away the other 49. And because each image is converted separately, auto page sizing is decided per image, so a 300 DPI scan gets a true A4 page even when the photo next to it in the batch does not.

Two source images that want the same output name - two folders can both hold IMG_0001.jpg - get IMG_0001.pdf and IMG_0001-2.pdf rather than one overwriting the other.

Records are pushed as each image is converted, so a run that dies at image 80 still has 79 results in its dataset.

How to convert PNG to PDF

Identical steps with .png files. PNG supports transparency and PDF pages are printed, so any transparent area is flattened onto white rather than coming out black. If the PNG is a screenshot or line art, set Quality to 100: that stores the image losslessly instead of as JPEG, which keeps small text crisp and is usually smaller as well.

How to convert HEIC to PDF

Upload the .heic file straight from an iPhone. The Actor reads the container to work out which codec is inside, so HEIC, HEIF and AVIF need no separate setting and no codec pack. There is nothing to convert to JPG first.

How to convert an image to PDF, whatever it is

WebP, TIFF, BMP and GIF go through the same path as everything else. There is one setting to be aware of: only the first page of a multi-page TIFF and the first frame of an animated GIF end up in the PDF. The run logs a warning when it sees either.

What page size should I choose?

This is the only setting worth thinking about, so it is worth two paragraphs.

auto gives every image a page of exactly its own size. Nothing is cropped, nothing is scaled and no white bands appear, which is what you want for scans, screenshots and anything read on a screen. When every image records the same sensible resolution, the page is that physical size - a set of 300 DPI A4 scans comes out as genuine A4 pages. Otherwise one pixel becomes one point, so a 4000 x 3000 photo produces a 4000 x 3000 point page. That page is large in inches, but it holds exactly the pixels you supplied and prints correctly with "fit to page".

a4, letter and legal put every image on a standard sheet, scaled to fit and centred, which is what you want when the PDF is going to be printed or filed. Orientation auto turns each sheet to match the image on it, so a landscape photo gets a landscape page rather than two white bands. Set Margin if you need white space around the edge; it is measured in points, and 72 points is one inch.

Input

Upload your images in the Images field, or pass direct URLs to them.

FieldDescription
filesThe images to convert, in page order. File uploads or URLs. Up to 100 per run.
fileA single image. A hidden alias of files, kept so existing API callers keep working.
mergeIntoOnetrue by default: one multi-page PDF. false gives one PDF per image, returned as a ZIP.
pageSizeauto (default), a4, letter or legal.
orientationauto (default), portrait or landscape. Applies to the fixed page sizes only.
quality1 to 100, default 90. 100 stores the images losslessly rather than as JPEG.
marginWhite margin around each image, in points. Default 0.
outputFilenameDefaults to the input filename for one image, and to images.pdf for several.
fileBase64, filenameA single image as base64, for API callers who prefer JSON to a URL.
verboseLogInclude the full ImageMagick output in the Actor log.

Output

What lands under OUTPUT - which is what the API returns in the response body - depends on the mode:

RunOUTPUTDataset records
Combining (default)The multi-page PDFOne, describing the whole PDF
Separate PDFs, one imageThat PDFOne
Separate PDFs, several imagesA ZIP of every PDFOne per image, in the order supplied
Separate PDFs, output over 192 MBA JSON manifest naming every PDFOne per image

Every PDF is also written under its own filename, so it is downloadable from the Storage tab, and so is the ZIP. The archive is assembled in memory, so past 192 MB of output the run skips it and writes a JSON manifest of the keys and URLs instead - the PDFs are all in the store either way. With several images and mergeIntoOne off, OUTPUT is always the archive, even if only one conversion succeeded - a script writing the response body straight to a file needs its shape to depend on what it sent, not on how many files happened to work.

Each dataset record holds the page count, the page size, the resolution the pages were built at, and the source images with their formats and dimensions. In the separate-PDFs mode it also carries ok and, when something went wrong, an error explaining what.

How much does it cost to convert JPG to PDF?

JobRun timeCost
One 12 MP photo6.7 s$0.0008
20 images merged into one A4 PDF18.3 s$0.0012
20 images as 20 separate PDFs32.8 s$0.0037

Measured 2026-08-26 on the Free plan at the default 1024 MB, read back from the run API.

A photo costs well under a cent, and Apify's free plan includes $5 of usage a month.

Merging is the cheap path. Twenty images into one PDF costs $0.0012; the same twenty as separate PDFs costs $0.0037, because each output file carries its own storage writes and its own trip through the encoder. Either way, one run beats twenty: several seconds of every run go on starting the container, and that is paid once per run rather than once per file.

Compute is roughly half the bill. The rest is key-value store writes and data transfer, which is why the separate-PDFs row costs three times the merged one despite doing the same conversion work.

Memory matters in exactly one case: a large batch merged into one PDF at a fixed page size. ImageMagick builds the whole document in a single pass and holds every page while it does, and an A4 page at 300 DPI is 8.7 megapixels before compression. The twenty-image run above fits in the default 1024 MB; a much larger one may not, and raising the memory is the fix. Note the trade is not free - the same merge at 4096 MB finished in 11.3 s but cost $0.0029, because you are billed for memory multiplied by time.

With mergeIntoOne off this does not apply. Images are converted one at a time and each source is deleted as it is dealt with, so no amount of pages ever meets in memory at once.

How to convert JPG to PDF with the API

run-sync returns the PDF in the response body:

curl -X POST \
"https://api.apify.com/v2/acts/marcel-rbro~jpg-to-pdf/run-sync?token=<TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"files": ["https://example.com/page-1.jpg", "https://example.com/page-2.jpg"], "pageSize": "a4"}' \
--output scan.pdf

A single image needs no list:

curl -X POST \
"https://api.apify.com/v2/acts/marcel-rbro~jpg-to-pdf/run-sync?token=<TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"file": "https://example.com/photo.jpg"}' \
--output photo.pdf

With mergeIntoOne off, the response body is a ZIP of one PDF per image, so write it to a .zip:

curl -X POST \
"https://api.apify.com/v2/acts/marcel-rbro~jpg-to-pdf/run-sync?token=<TOKEN>" \
-H 'Content-Type: application/json' \
-d '{"files": ["https://example.com/a.jpg", "https://example.com/b.jpg"], "mergeIntoOne": false}' \
--output pdfs.zip

The dataset then holds one record per image, each with an ok flag, so a caller that needs to know which files failed reads it from GET /v2/datasets/{id}/items rather than guessing from the archive.

If you hold the bytes rather than a URL, pass them as base64 in fileBase64:

curl -X POST \
"https://api.apify.com/v2/acts/marcel-rbro~jpg-to-pdf/run-sync?token=<TOKEN>" \
-H 'Content-Type: application/json' \
-d "{\"fileBase64\": \"$(base64 < photo.jpg)\", \"filename\": \"photo.jpg\"}" \
--output photo.pdf

Base64 adds about a third to the payload and takes one image at a time, so prefer URLs for anything large or for a batch.

Actor input has to be application/json on every endpoint - a request that posts the image bytes as the request body is rejected with HTTP 400 before the run even starts. URLs and base64 are the two ways in.

run-sync waits up to 300 seconds, which is ample for a normal batch. Use the asynchronous Run Actor endpoint for a very large one. There are client libraries for JavaScript and Python, and the same run can be triggered on a schedule or from Zapier, Make, n8n, Slack or an MCP client.

Limitations

  • The PDF holds pictures, not text. There is no OCR, so the result is not searchable and you cannot select a sentence out of it. A photograph of a page stays a photograph of a page.
  • It writes PDFs, it never reads them. You cannot add pages to an existing PDF, merge two PDFs, or pass a PDF as input. Reading PDFs needs Ghostscript, which is deliberately absent from the image.
  • Up to 100 images per run, whether they become one PDF or many, with 512 MB of input in total, 100 MB for any single file, 100 megapixels in one image and 2 gigapixels across the run. The pixel ceilings are the ones you meet first with camera files: 100 photos from a 12 MP phone is around 1.2 gigapixels and fits comfortably, while a batch of large scans may not. Each limit is refused up front with a sentence naming it and the number that hit it, so nothing is converted before the run stops. A larger batch means splitting it across runs.
  • An oversized single file fails the run rather than being skipped. Every input is downloaded before the mode is known, so a file over the 100 MB ceiling is caught after its bytes are already committed. Per-file isolation covers conversion failures, not download-size ones.
  • Only the first page or frame of a multi-page TIFF or an animated GIF is used. The run warns when it sees one.
  • Vector formats are out of scope. SVG, EPS and PDF input are rejected with an explanation rather than a delegate error. Render them to PNG first.
  • A failure is only isolated when the PDFs are separate. Combining is all or nothing: one unusable image invalidates the single document, so the run stops and says which file it was. With mergeIntoOne off, that image is skipped and the rest still convert.
  • Fixed page sizes scale images to fit, enlarging a small one to fill the sheet. That cannot add detail the image never had. Use auto to keep every pixel exactly as it was.
  • HEIC input depends on the container's libheif delegate. The build asserts that JPEG, PNG, WebP, TIFF, BMP and GIF can be read and that PDF can be written, and logs a warning rather than failing if HEIC support has gone missing from the Debian package.

Other file converters

ActorConverts
JPG to PDF converter (this one)JPG, PNG, WebP, TIFF, BMP, GIF, HEIC → PDF
PDF to JPG converterPDF → JPG, PNG
HEIC to JPG converterHEIC, HEIF, AVIF → JPEG, PNG, WebP, AVIF, TIFF
PNG to JPG converterPNG → JPG
Word to PDF converterDOC, DOCX → PDF
EPUB to PDF converterEPUB → PDF
MOBI to EPUB converterMOBI, PRC, AZW, AZW3 → EPUB

FAQ

Is this JPG to PDF converter free?

Apify's free plan includes $5 of platform usage per month and needs no card. A conversion costs a fraction of a cent, so that covers a great many PDFs before you pay anything.

Does converting JPG to PDF lose quality?

At the default quality of 90, not visibly. The images are re-encoded as JPEG inside the PDF, which costs a little on top of whatever the source had already lost. Set Quality to 100 to store them losslessly instead - larger files, but the pixels that go in are the pixels that come out. With Page size set to auto and quality 100, nothing is resampled or re-encoded at all.

One PDF or one PDF per image - which do I get?

Both are the same input field, so this is worth being explicit about. Combine into one PDF is on by default, and every image becomes a page of one document, in the order you listed them. That is what most people mean by converting a stack of scans.

Turn it off and each image becomes its own PDF instead, returned as a ZIP. Choose that when you have 50 receipts that need to stay 50 separate files. Nothing else about the conversion changes - page size, orientation, margin and quality all work the same either way.

Can I choose the order of the pages?

Yes, and it is the order you list the files in. The Actor does not sort them, guess from filenames, or reorder anything. Page one is the first file in the list.

Is the text in the PDF searchable?

No. This is an image-to-PDF converter, not an OCR tool: each page is a picture of your image. If you need selectable text, run the PDF through an OCR tool afterwards.

Can I convert a PDF back to JPG?

Not here - this Actor only writes PDFs. Use the PDF to JPG converter for the other direction.

How do I batch convert a whole folder?

Pass every file in the files list in one run, and decide with mergeIntoOne whether you want one PDF or one per image. Either way a batch is much cheaper than one run per file, because container startup costs more than the conversion does. For more than 100 images, split it across runs.

Can an AI agent call this converter?

Yes. Every Apify Actor is exposed through the Apify MCP server, so Claude, Cursor and other MCP clients can run this conversion as a tool.

The conversion failed. What now?

The Actor names the problem in its status message before it tries to convert anything, so start there. The usual causes are a URL that returns a login or error page rather than an image, a .mov from a Live Photo passed in place of the .heic still, and a file that is already a PDF. Turn on verboseLog and re-run for anything else: the Actor log will then carry ImageMagick's own output.

Development

npm install
npm test # tests the image header inspector, no ImageMagick needed
apify run # needs ImageMagick on your PATH

Conversion runs ImageMagick in a Debian container. Combining writes every page of the PDF in one pass; converting separately runs ImageMagick once per image. src/zip.js, which packs a batch of separate PDFs into one download, and src/batch.js, which holds the run's budgets and key de-duplication, are shared with the sibling converters rather than added as dependencies. Both are pure and unit-tested without an engine. ImageMagick 7 renamed convert to magick; the Actor detects which one is present, so local development on macOS works the same as the Debian image.

Ghostscript is deliberately not installed. It is what ImageMagick uses to read PDF and PostScript, and this Actor only writes PDFs - leaving it out removes ImageMagick's largest attack surface at no cost, and Debian's default security policy is edited to permit writing PDFs while still refusing to read them.

This Actor's code is MIT licensed. ImageMagick and libheif run as separate processes or shared libraries under their own licences - see THIRD_PARTY_NOTICES.md.