Image to PDF

Turn a batch of images into one PDF — receipts into an expense report, screenshots into documentation, scans into a submission. Order the pages, pick a page size, and the PDF is assembled entirely in your browser by this site's own tested writer.

Combine images into a PDF

Add images (JPG, PNG, WebP, GIF, BMP), arrange them with the Up/Down buttons, then create the PDF.

or drag and drop images here — they append to the list

Up to 20 images · 100 MB each · 80 megapixels per PDF session

    How your images become pages

    Each image occupies exactly one page, in your list order; adding files appends to the list, and the Up/Down buttons reorder it before anything is encoded. The size of every page and the placement of its image are decided by one pure function in the writer, from four inputs: the image's pixel dimensions, the page mode, the DPI field, and the margin. With "match each image" the page is the image. An illustrative 1920×1080 screenshot at the writer's default of 96 DPI becomes a 1440×810-point page with both offsets at zero, by the writer's own rule points = pixels × 72 ÷ DPI — 72 points to the inch is the unit the writer itself defines, read back here rather than typed. Declare an illustrative 300 DPI instead and the same screenshot becomes a 460.8×259.2-point page; the embedded JPEG still declares 1920 by 1080 pixels, because the DPI field states a physical size and never resamples anything.

    A4 and Letter are constants in the writer — 595.28×841.89 points and 612×792 points — and in either mode the image is scaled to fit inside the half-inch margin the methodology page describes, 36 points on every side (the build asserts that the writer's default margin is still half of 72), and then centered. An illustrative 3024×4032 receipt photo measures 2268×3024 points at 96 DPI; on A4 it is width-bound and drawn at 523.28×697.71 points, offset 36 points from the left and 72.09 from the bottom. On Letter the same photo happens to share the aspect ratio of the area inside the margins, so it fills that area exactly: drawn at 540×720 points with both offsets at 36 — a coincidence the build checks rather than assumes. An illustrative 1280×720 screenshot on Letter is width-bound, drawn at 540×303.75 points and lifted 244.13 points from the bottom edge, with the same space above it. Nothing is cropped or stretched: both dimensions share one scale factor, so the aspect ratio survives by construction.

    Guide: Image to PDF: page math. The full derivation lives there — why DPI cancels out of the A4 and Letter fit, how an image smaller than the margins is scaled up to meet them, and the writer's syntax quoted from real builds on fixtures. This page covers what the tool decides about the images you add.

    What the detector sees in each image you add

    Before any image is decoded, its leading bytes are read and matched against the format signatures the engine knows; the name of the file plays no part in the reading. Run at build time on constructed byte arrays, the detector reports PNG for the eight bytes 89 50 4E 47 0D 0A 1A 0A, JPEG for bytes beginning FF D8 FF, WebP for RIFF…WEBP, GIF for GIF89a, and BMP for a header beginning BM — the five formats this tool lists. The filename is then compared with that reading. For scan-01.png whose bytes really are PNG, the check returns actual PNG, claimed PNG, mismatch false: nothing to report. For receipt-03.jpg whose bytes begin with the PNG signature, it returns actual PNG, claimed JPEG, mismatch true: the image is decoded from its bytes and treated as the PNG it is — which matters here, because a PNG's transparency is flattened and a JPEG has none to flatten. The converter pages surface that mismatch as the visible notice the methodology page describes; this tool's list rows name each file and its size, and add a note only for an animated image, so the misnaming is not repeated there — the decode is driven by the bytes regardless.

    Detection is a pure function over bytes: no decoding has happened yet, nothing has been sent anywhere, and the answer does not depend on which browser is running it. The same function runs once more at the other end of this tool, inside the writer, which sniffs every JPEG it is handed before reading its frame header.

    What the plan decides for each source format

    The writer accepts JPEG bytes and nothing else, so every image you add is re-encoded as JPEG whatever format it arrived in. The planning table every converter on this site consults records, for a JPEG target, that the format can carry per-pixel transparency: no; and that it is lossy: yes. Run for each format this tool accepts, with a JPEG target, the planner returns the following verdicts — computed at build time by the planning module the converter pages run; this tool applies the JPEG column unconditionally:

    The planner's verdicts for a JPEG target, per source format
    Source Flatten onto a background First frame only
    JPEG false false
    PNG true false
    WebP true true
    GIF true true
    BMP true false

    So PNG, WebP, GIF, BMP sources carry a flatten flag, and WebP and GIF sources carry the first-frame flag; the planner decides both from the formats, not by inspecting your pixels. Unlike the converter pages, which ask for the color before converting (the prompt the methodology page describes), this tool has no background control: it composites every image onto white — the same #ffffff the planner uses as its default background — and states that difference here, before you build. For a JPEG source the flatten flag reads false — there is nothing to flatten — yet the pixels are still decoded, drawn, and re-encoded, because the writer embeds the JPEG the tool produced, not the file you added. An animated GIF or WebP contributes its first frame, and its row in the list says so; animation is detected by counting GIF image descriptors and by reading the WebP VP8X flag and ANIM chunks, so the note appears exactly when it applies.

    The quality slider's value goes to the browser's own JPEG encoder — the canvas re-encode the methodology page describes, not the MozJPEG lane, which this site uses only on Compress JPEG. The engine keeps quality on a 0–1 scale; the planner's own default for a JPEG target, 0.92, is 92 on the whole-number scale the slider uses. This tool starts its slider where the control above shows and uses whatever value is set when you press Create PDF; the planner's accepted bounds are stated in its own refusal, "Quality must be between 0.05 and 1." The site publishes no recommended setting and no blanket compression percentages, because no setting and no percentage is true for every image. What you get instead is a measurement: the result line reports the finished PDF's true byte count, so two runs at different settings compare real files.

    What the writer embeds — and what it does not

    For each page the writer emits a page object, a content stream that draws the image into the rectangle computed above, and an image XObject whose data is the JPEG bytes embedded verbatim under the /DCTDecode filter — no further encoding, no second compression. It reads one thing from each JPEG: the start-of-frame header. For a three-component stub it reads 1920×1080 with 3 components and writes /DeviceRGB; a one-component frame (1 component, 1240×1754) is written as /DeviceGray, and a four-component frame (4 components, 600×400) as /DeviceCMYK — the color space comes from the frame header, as the methodology page states, never from a guess. The reader refuses a marker stream with no frame header or one reporting zero dimensions, so no page is ever sized from a default.

    What the writer does not embed is everything that stood beside the pixels in your original file. Because every image passes through a canvas before it reaches the writer, the re-encode strips all embedded metadata: EXIF including GPS location, camera model, and timestamps; color-profile tags; and text chunks. The methodology page presents this as both a feature and a caveat, and it is both — a PDF built here cannot leak where a receipt was photographed, and equally, copyright fields and profiles are gone, so keep your originals. Orientation is the one thing applied before it is discarded: decoding uses imageOrientation: 'from-image', so a photo whose metadata says it is rotated comes out upright on the page even though the tag itself does not survive. The PDF adds no metadata of its own, either: the trailer of the illustrative build reads << /Size 12 /Root 1 0 R >> — an object count and a catalog reference, no title, author, or date. The metadata guide sets out the full list.

    How the output is verified before download

    The writer's layout is fixed: a catalog, a page tree, and three objects per image. An illustrative three-image session — the screenshot, the receipt, and the wide screenshot above, on Letter — built at build time by the real writer on stub JPEGs opens with the header %PDF-1.4, contains 11 objects of which 3 are page objects, declares /Count 3 on its page tree and /Size 12 in its trailer (one more than the object count, for the free entry at index zero), points startxref at byte 1479 — where the bytes read xref, checked at build — and ends with %%EOF. Every one of the three stub JPEGs is found byte for byte inside the output, and the build fails if one is not. The structure around them costs 1596 bytes for these stubs: an illustrative figure that real JPEGs dwarf, which is why the finished file weighs the sum of its re-encoded pages plus a small structural remainder.

    These are the same properties the writer's tests pin — header, object count, cross-reference offsets, EOF marker, and the byte-for-byte JPEG round-trip — and when you press Create PDF the client re-checks the assembled structure before offering the download, so the "Verified structure" badge is earned rather than asserted. The writer also refuses rather than guesses, and each refusal carries a plain message: an empty list, "Add at least one image to build a PDF."; a DPI outside the range the control above enforces, "DPI must be between 24 and 600."; and bytes that are not JPEG — here the eight-byte PNG signature slipped in as the second image — "Image 2: Not a JPEG file (missing FF D8 FF signature)." That last check is also what would catch a browser quietly producing something other than JPEG from the canvas: the writer refuses the bytes by position rather than embedding a mislabeled stream.

    Limits this tool applies

    The panel above states this tool's own rules; in addition, each image is subject to the per-image input limit of 50 megapixels the methodology page states. They exist to keep a browser tab responsive, and they are stated before you build rather than discovered on failure. Oversized photos can be scaled first with the Image Resizer, whose arithmetic is set out in Resizing math.

    What the tool cannot know

    The plan and the geometry are decided from formats, pixel counts, and the two controls, so there are things this tool does not and cannot judge. It does not know whether a PNG or WebP actually uses its alpha channel — only that those formats can carry one and JPEG cannot — hence the unconditional flatten. It does not know what physical size you intend: the DPI field is your statement, recorded as given. It does not know how a viewer will render the pages; it writes a transformation and an image stream and stops there. It does not know whether a re-encoded page looks acceptable to you: the JPEG target is lossy by capability (yes), the pixels are not reproduced exactly, and the only honest statements the tool can make about the result are its verified structure and its measured size. And it does not know which pages belong together — that is the ordering the Up/Down buttons exist to let you decide.

    Common misreadings

    • "JPEG inputs are copied into the PDF untouched." They are decoded, drawn, and re-encoded like every other input; the plan's flatten flag for a JPEG source is false, but the re-encode still happens, and the writer embeds the JPEG the tool produced.
    • "A transparent PNG stays transparent on the page." The flatten flag for a PNG source is true, and this tool composites onto #ffffff without asking.
    • "An animated GIF becomes an animated page." The first-frame flag for a GIF source is true: one frame, one page, and the row says so.
    • "The extension decides how a file is read." The bytes do. A .jpg that is really PNG is decoded and treated as PNG, whatever its name says; this tool's list does not repeat the notice the converter pages show.
    • "The PDF keeps my photos' EXIF and GPS." It cannot: the metadata is stripped by the canvas re-encode before the writer ever sees the bytes, and the PDF writes no document information of its own.
    • "The quality slider changes the page size." It changes only the JPEG encode; page size comes from the pixel dimensions, the page mode, and the DPI field.
    • "Objects are pages." The three-image build has 11 objects but 3 pages; the writer emits three objects per image plus a catalog and a page tree.

    Shrink oversized photos with the Image Resizer before combining — smaller inputs, smaller PDF. To fix formats first, the converters are in the sidebar: WebP to JPG and PNG to JPG pair naturally with PDF building. The mechanisms behind every page are written up in the guides; for this tool, start with Image to PDF: page math.

    Frequently asked questions

    How are my images arranged in the PDF?

    One image per page, in the order shown in the list — use the Up/Down buttons to reorder before creating. Files you add in one go keep their selection order, and adding more files appends them to the end.

    What do the page size options mean?

    "Match image" sizes each page to its image at your chosen DPI — an illustrative 1920×1080 screenshot at 96 DPI becomes a 1440×810-point page with no borders. A4 (595.28×841.89 points) and Letter (612×792 points) produce uniform pages with the image scaled to fit inside a half-inch margin — 36 points on every side — and centered, never cropped or stretched.

    What does the DPI setting change?

    Only the page size declared in "match image" mode: points = pixels × 72 ÷ DPI, so the same illustrative 1920×1080 screenshot is a 1440×810-point page at 96 DPI and a 460.8×259.2-point page at an illustrative 300. The embedded pixels are identical either way, and on A4 and Letter the fit arithmetic cancels DPI out entirely — the page-math guide shows why.

    Are the images recompressed?

    Yes. Every page is re-encoded as JPEG at the slider's value, because the writer embeds JPEG streams and nothing else — JPEG inputs included. The planning table flags a background flatten for PNG, WebP, GIF, BMP sources (the flag reads true for PNG), and this tool composites onto #ffffff without asking — stated here, before you build. The site publishes no recommended quality setting; the result line reports the PDF's true byte count.

    What happens to an animated GIF or WebP?

    Its first frame becomes the page. The plan's first-frame flag is decided from the container type — true for a GIF source, true for WebP, false for PNG — and animation itself is detected by counting GIF image descriptors or reading the WebP VP8X flag and ANIM chunks, so the "first frame only" note on the row appears exactly when it applies.

    What if a file is named .jpg but is really a PNG?

    The bytes win. Run at build time, the extension check on receipt-03.jpg whose bytes begin with the PNG signature returns actual PNG, claimed JPEG, mismatch true: the image is decoded from its bytes as the PNG it is, so any transparency is flattened like any other PNG's. The converter pages show that mismatch as a notice on the file's row; this tool's list names each file and its size without repeating it.

    Which PDF library does this use?

    None — the PDF is assembled byte by byte by this site's own writer of about two hundred lines. Its tests assert the header, the object count, the cross-reference offsets, the EOF marker, and that each JPEG round-trips byte for byte; the illustrative three-image build on this page declares 11 objects and a trailer /Size of 12. The client re-checks the assembled structure before the download appears.

    Do my images or the PDF touch a server?

    No. The images are read, encoded, and assembled into the PDF inside your tab, and the download comes from browser memory. The methodology page shows how to verify zero network traffic.

    Local processing: images and the finished PDF exist only in your browser until you save them. How the writer works — and how to verify nothing is uploaded — is on the methodology page.