For a single PNG, Pillow can write a PDF directly. For several images that should become one PDF, use img2pdf for a concise, often lossless conversion; choose ReportLab when you need to design page layouts, or PDFKit for JavaScript applications. The important decisions are image ordering, color mode and transparency, page dimensions, and whether the output must preserve the original pixels.
Choose the right conversion method
| Tool | Runtime | Best fit | Layout and output |
|---|---|---|---|
| Pillow | Python | A direct single-image export or a basic multipage PDF | Simple PDF saving; page dimensions depend on image pixels and metadata |
| img2pdf | Python or command line | Combining images into a PDF while preserving supported source image data | Focused conversion rather than adding designed page content |
| ReportLab | Python | Pages with captions, headers, footers, shapes, or precise placement | Canvas gives control over page size and element positions |
| PDFKit | Node.js or browser | PDF generation in a JavaScript application | Node can write a stream to a file; browser output uses a stream/blob workflow |
Use Pillow when the task is just saving an image as a PDF. Use img2pdf when batch conversion and retaining original image data matter. ReportLab or PDFKit are better when the PDF is a composed document rather than a container for an image.
Convert one PNG to PDF with Pillow
Install Pillow in the Python environment where you will run the script:
python -m pip install Pillow
Save this as png_to_pdf.py beside input.png, then run python png_to_pdf.py:
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
- Convert your PDF files into Word, Excel & Co. the easy way
- Convert scanned documents thanks to our new 2022 OCR technology
- Adjustable conversion settings
- No subscription! Lifetime license!
- Compatible with Windows 11, 10, 8.1, 7 - Internet connection required
from PIL import Image
with Image.open("input.png") as image:
image.save("output.pdf", "PDF")
Pillow’s format documentation states that it can write PDF (Acrobat) images. Its PDF output is binary PDF 1.4. The minimal example is convenient, but it does not explicitly define a paper size or decide how alpha transparency should appear in every target PDF viewer. If the PNG has an alpha channel, choose the desired background rather than assuming every viewer will display transparency identically.
Make transparency handling explicit
For a broadly compatible result with transparency flattened onto white, composite the PNG over a white background and convert to RGB before saving:
from PIL import Image
with Image.open("input.png") as source:
rgba = source.convert("RGBA")
background = Image.new("RGBA", rgba.size, "white")
flattened = Image.alpha_composite(background, rgba).convert("RGB")
flattened.save("output.pdf", "PDF")
This deliberately discards transparency by placing transparent pixels over white. Change the background color if white is not appropriate. If retaining transparency is a requirement, test the result in the PDF viewers and downstream tools that matter to you; do not use this flattening recipe.
Why image mode affects the result
Pillow’s PDF encoder handles modes differently: 1-bit images use TIFF or JPEG fallback, L/RGB/CMYK use JPEG, palette images use hexadecimal encoding, and LA/RGBA use JPEG2000. Consequently, converting to RGB is a practical compatibility choice when transparency is unnecessary, but it is not a neutral operation: it changes the mode and can flatten or otherwise alter how image data is represented. Check color and transparency in the saved document instead of assuming every input mode maps to the same PDF encoding.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Combine multiple PNGs into one PDF
For straightforward batch conversion, img2pdf is designed to convert images to PDF. The project documents PNG, JPG/JPEG, WebP, BMP, GIF, and TIFF input, including multiple files combined into one document.
Rank #2
- Convert over 50 document file formats.
- Preview your files from Doxillion before converting them.
- Use batch conversion to convert thousands of files at once.
- Enjoy an easy-to-use, intuitive interface with a Drag and Drop file option.
- Burn your converted or original files directly to disc.
python -m pip install img2pdf
img2pdf --output out.pdf page1.png page2.png page3.png
Arguments are supplied in document order: page1.png becomes the first page, followed by page2.png and page3.png. For a generated batch, sort filenames deliberately before passing them; filesystem enumeration order is not a reliable page-order policy. If names include numbers, use natural numeric ordering so, for example, page 10 does not accidentally precede page 2.
The img2pdf project documents lossless conversion for PNG, JPEG, and JPEG2000 inputs where supported, adding PDF container overhead rather than re-encoding the image pixels. That makes it a strong choice for scans or screenshots when preservation of source pixels matters more than custom layout. Do not infer that every supported input format is lossless in every case; the stated lossless handling applies to those documented formats where supported.
Batch conversion from Python
Use a sorted, explicit path list when the files are generated or selected in code:
import img2pdf
paths = ["page-1.png", "page-2.png", "page-3.png"]
with open("out.pdf", "wb") as output:
output.write(img2pdf.convert(paths))
This collects the conversion result before writing it. For very large jobs, consider the command-line workflow or a design that processes a manageable batch at a time, and monitor memory use. The most appropriate method depends on file sizes and the surrounding application; the available documentation does not establish comparative speed or memory benchmarks.
Control page layout with ReportLab
ReportLab’s pdfgen canvas lets you place an image and other drawn content at exact coordinates. Use it when each PNG needs a caption, a header or footer, a border, or a fixed page size. Install the library with python -m pip install reportlab. Its guide notes that the Python Imaging Library is needed for non-JPEG images; Pillow supplies that image support.
Rank #3
- EDIT text, images & designs in PDF documents. ORGANIZE PDFs. Convert PDFs to Word, Excel & ePub.
- READ and Comment PDFs – Intuitive reading modes & document commenting and mark up.
- CREATE, COMBINE, SCAN and COMPRESS PDFs
- FILL forms & Digitally Sign PDFs. PROTECT and Encrypt PDFs
- 1 Year License for 1 Windows & 2 Mobile (Android and/or iOS) devices.
from PIL import Image
from reportlab.lib.utils import ImageReader
from reportlab.pdfgen import canvas
with Image.open("input.png") as image:
width, height = image.size
pdf = canvas.Canvas("output.pdf", pagesize=(width, height))
pdf.drawImage(ImageReader(image), 0, 0, width=width, height=height)
pdf.showPage()
pdf.save()
This uses the image’s pixel dimensions as the page dimensions in PDF points. PDF points are not pixels: one point is 1/72 inch. Thus, a page that is 1200 units wide in this example is 1200 points wide, not a typical 1200-pixel image printed at a particular physical resolution. For a standard paper page or a deliberate print size, set the page size and scale the image explicitly.
Fit an image to a fixed page without stretching
To fit an image inside a page while preserving its aspect ratio, calculate a single scale factor and center the result. This example uses an A4-sized page in points:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallfrom PIL import Image
from reportlab.lib.utils import ImageReader
from reportlab.pdfgen import canvas
page_width, page_height = 595.28, 841.89
margin = 36
with Image.open("input.png") as image:
image_width, image_height = image.size
scale = min(
(page_width - 2 * margin) / image_width,
(page_height - 2 * margin) / image_height,
)
draw_width = image_width * scale
draw_height = image_height * scale
x = (page_width - draw_width) / 2
y = (page_height - draw_height) / 2
pdf = canvas.Canvas("output.pdf", pagesize=(page_width, page_height))
pdf.drawImage(ImageReader(image), x, y, width=draw_width, height=draw_height)
pdf.showPage()
pdf.save()
The margin in this example is 36 points on each side. The image is fitted inside the remaining area and centered; it is not enlarged beyond the space available. For print-oriented output, derive physical dimensions from a chosen DPI rather than treating pixels as points. DPI metadata and the desired output page dimensions are separate concerns, so set the intended geometry explicitly when it matters.
Generate a PDF with PDFKit in Node.js
PDFKit is a PDF document generation library for Node and the browser. For Node.js, install it with npm install pdfkit. This example creates a page and fits the PNG within a 595-by-842-point area:
const PDFDocument = require('pdfkit');
const fs = require('node:fs');
const doc = new PDFDocument({ autoFirstPage: false });
doc.pipe(fs.createWriteStream('output.pdf'));
doc.addPage();
doc.image('input.png', 0, 0, { fit: [595, 842] });
doc.end();
The example uses the Node filesystem, so it is not a browser snippet. In browser builds, PDFKit documents collecting its output as a stream/blob; browser code must supply image bytes or registered data rather than asking the browser to read a local filesystem path. Choose the output mechanism that matches the runtime and wait for the stream/blob to finish before treating the PDF as complete.
Rank #4
- Perfect Adobe Acrobat Pro alternative – lifetime license for Windows 10 and 11.
- EDIT text, images, pages, hyperlinks, designs in PDF documents. ORGANIZE PDFs.
- READ and Comment on PDFs – Intuitive reading modes & document commenting and mark up tools!
- CREATE, COMBINE, SCAN and COMPRESS PDFs.
- FILL forms & Digitally Sign PDFs. Work with Digital certificates
Check quality, ordering, and reliability
- Confirm page order: provide paths in an explicit order and inspect the generated PDF’s page sequence.
- Check page count: verify that the output has one page per intended image, especially after a batch run.
- Inspect alpha: compare transparent edges against the intended background in the PDF viewer or application that will consume the document.
- Verify dimensions: distinguish pixel dimensions from PDF points and set a page size, margins, and scale when printing or fitting to paper matters.
- Open the actual output: confirm the PDF opens in the target viewer and that colors, cropping, and image orientation are acceptable.
- Plan for large inputs: decoding very large PNGs can consume substantial memory. Avoid loading an entire oversized batch at once where possible; resize only if reducing pixel detail is acceptable.
No directly comparable conversion-speed or file-size benchmarks are established for these libraries here. Actual runtime and output size depend on image dimensions, modes, encoding choices, layout, and the implementation.
Troubleshooting common conversion problems
The output PDF has an unexpected page size
Pillow’s PDF physical dimensions are influenced by pixel count and image metadata. With ReportLab, the canvas page size is whatever dimensions the code supplies, and those are measured in points. Set page geometry explicitly with a layout tool when a specific paper size or print scale is required.
Transparent areas appear black, colored, or opaque
Viewer and encoder handling can differ by mode. If transparency is not needed, explicitly composite onto the intended background and convert to RGB before saving. If it is needed, preserve it and verify the output in the destination viewer rather than flattening it.
The PDF pages are in the wrong order
Batch order follows the paths supplied to the conversion. Build a deterministic, explicitly sorted list; do not rely on the order returned by an arbitrary directory scan.
A non-JPEG image fails in a ReportLab workflow
ReportLab’s guide identifies the Python Imaging Library as necessary for non-JPEG images. Install Pillow and pass an image through ImageReader, as in the example.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsBest Value
- Convert over 50 document file formats.
- Preview your files from Doxillion before converting them.
- Use batch conversion to convert thousands of files at once.
- Enjoy an easy-to-use, intuitive interface with a Drag and Drop file option.
- Burn your converted or original files directly to disc.
A Node script creates an empty or incomplete PDF
PDFKit writes through a stream. Ensure the document is piped to a writable destination and that your application waits for output completion before reading, moving, or returning the file. Call doc.end() after adding pages and images.
The conversion is too memory-intensive
Large PNGs must be decoded, and a Python list of open images or an accumulated conversion result can increase peak memory. Reduce batch size, close images promptly, or resize before conversion only if the lower resolution is acceptable. There are no established benchmark figures here that identify one library as universally fastest.
Or skip the browser setup
If what you need is a PDF of a web page rather than conversion of existing PNG files, ScreenshotNeo captures a URL as a PDF. It is a website screenshot API and MCP server from Yorker Media; it is not a PNG-to-PDF library, so use the code below for a webpage capture instead of a local image conversion.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options; choose the PDF output format for a PDF capture. ScreenshotNeo accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture, with each step switchable. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 shots monthly with no card; paid plans start at $5 for 3,000 shots.
Free tools Windows power users keep installed
One-click scans. No signup required.
Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.
Frequently Asked Questions
Can I combine PNGs with different dimensions in one PDF?
Yes. A conversion tool can place them on separate pages, but consistent paper size and scaling require an explicit layout choice. Use ReportLab or PDFKit when each image must be fitted to a common page.
Will a PNG-to-PDF conversion make a small PNG suitable for print?
Conversion does not add image detail. Set the intended physical page dimensions and check the effective resolution at that size; enlarging a low-resolution image cannot recover missing pixels.
Which option is best for a browser-based JavaScript app?
PDFKit supports browser use, but the browser workflow supplies image bytes or registered data and collects the generated stream/blob rather than reading a local file path.
Quick Recap
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.

