Images are often the dominant contributor to PDF file size. A single high-resolution photograph can be larger than all the text and vector content in an entire document. Understanding how PDF stores, compresses, and manages raster images is essential for producing PDFs that balance visual quality against file size — and for diagnosing issues like blurry print output, colour shifts, or unexpectedly large files. PDF stores raster images as Image XObjects — stream objects containing raw or compressed image data with metadata (width, height, colour space, bits per component) in the stream dictionary. Images are positioned on pages using the Do content stream operator, which paints the image into the current transformation matrix.

Image XObject structure

An Image XObject is a stream dictionary with specific required entries: /Type /XObject, /Subtype /Image — Identifies the object as an image. /Width, /Height — Image dimensions in pixels (samples). /ColorSpace — The colour space of the image data: /DeviceGray, /DeviceRGB, /DeviceCMYK, [/ICCBased iccStreamRef], /Indexed, etc. See PDF Colour Space. /BitsPerComponent — Bit depth per colour channel: 1, 2, 4, 8, or 16. /Filter — The compression filter applied to the image data. Can be a single filter name or an array of filters applied in sequence. /SMask — An optional soft mask image (a second Image XObject in DeviceGray) providing per-pixel opacity for the image. /Interpolate — Boolean: if true, the viewer should interpolate (smooth/upsample) the image when rendering at larger than native resolution. /ImageMask — Boolean: if true, the image is a 1-bit stencil mask rather than a colour image. The current fill colour is used to paint through the mask. The image stream data follows the dictionary, compressed according to the /Filter entries. Invoking an image on a page — An image is painted onto a page by: saving the graphics state (q), setting a transformation matrix that specifies the image's position and size (w 0 0 h x y cm), invoking the image resource (/ImgName Do), and restoring state (Q). The width (w) and height (h) in the cm matrix are in user space units (points), not pixels — this is how an image can be placed at any size independent of its pixel dimensions.

Compression filters for images

The image quality and file size relationship is primarily determined by the compression filter choice. PDF supports several image compression filters, each suited to different image types. DCT (JPEG) — /DCTDecode — Lossy compression using the JPEG DCT algorithm. Best for photographs and complex natural images. Quality is controlled by the /QFactor parameter (0.0 = maximum quality, 1.0 = maximum compression). At quality 0.5 (medium JPEG), a photograph that would be 5 MB uncompressed compresses to ~500 KB with good visual quality. JPEG is not appropriate for line art, text, or images requiring exact reproduction — DCT introduces visible artefacts at block boundaries for high-contrast content. Flate (Deflate/zlib) — /FlateDecode — Lossless compression based on the DEFLATE algorithm (used by zlib and ZIP). Suitable for all image types but best for images with large flat areas of colour, screenshots, and diagrams. PNG images in a PDF are stored with FlateDecode. Compression is controlled by /Predictor: PNG predictor (value 15) dramatically improves compression for photographic content stored losslessly. JPEG 2000 — /JPXDecode — Wavelet-based compression. Both lossy and lossless modes. Significantly better quality-to-size ratio than JPEG at high compression; better lossless compression than Flate for photographs. Used in PDF/X-4, PDF/A-2, and PDF/A-3. Not supported in PDF 1.3 or earlier. Slower to decode than JPEG — affects render speed for image-heavy PDFs on older viewers. JBIG2 — /JBIG2Decode — Specialised compression for bi-tonal (black-and-white) images. Dramatically better than CCITT Group 4 for scanned text documents. Achieves 5–10× compression improvement over Group 4 on typical scanned text. JBIG2 is the compression used by Acrobat Pro's "ClearScan" and high-quality scan-to-PDF workflows. CCITT Group 3/4 — /CCITTFaxDecode — Legacy fax-era compression for 1-bit images. Group 4 (the 2D variant) is still widely used for scanned documents in workflows with legacy infrastructure. Lossless. JBIG2 supersedes it for quality but Group 4 has broader compatibility. Run Length — /RunLengthDecode — Very simple lossless compression for images with long runs of identical bytes. Rarely used directly; typically used as a pre-filter before LZW.

Resolution: DPI, PPI, and PDF rendering

Image resolution in PDF involves understanding the distinction between the image's pixel dimensions, the size it is rendered on the page, and the effective DPI at output. Effective DPI calculation — A 1200×1600 pixel image placed in a 4×5.33 inch area on a page has an effective resolution of 300 DPI (1200÷4 = 300). The same image placed in a 2×2.67 inch area has an effective resolution of 600 DPI. The PDF does not store a DPI value for an image — DPI is an emergent property of pixel count divided by physical dimensions. Resolution requirements by output type: - Commercial print (offset, laser): 300 DPI minimum at final output size. 400–600 DPI for small type or fine detail. Below 250 DPI, softness is visible at normal reading distance. - Wide-format print (posters, banners): 100–150 DPI at final size is typical. Viewed from greater distance, lower resolution is acceptable. - Screen display: Screen PDF display is resolution-independent because viewers can zoom. However, images below 72 DPI at display size will appear soft at 100% zoom on typical screens. - OCR source images: 300 DPI minimum for reliable OCR; 400 DPI for small fonts or slightly degraded documents. Downsampling in PDF creation — Adobe Acrobat and InDesign downsample images during PDF creation based on output intent: the "ebook" PDFMARK setting downsamples images to 150 DPI; "print" to 300 DPI. When creating PDF/X for commercial print, use "prepress" quality settings which preserve source resolution. Downsampling is permanent — it cannot be reversed. The /Interpolate flag — Setting /Interpolate true on an Image XObject instructs the viewer to bilinearly interpolate the image when rendering at larger than native resolution. This improves visual appearance of low-resolution images on screen but has no effect on print output (which uses its own scaling).

Extracting and auditing images in PDFs

Extracting images with pdfimages — The pdfimages command (Poppler) lists and extracts images from a PDF: pdfimages -list document.pdf — Lists all images with resolution, size, colour space, and encoding. pdfimages -all -png document.pdf extracted/img — Extracts all images as PNG files. Auditing with Acrobat Pro — Print Production > Output Preview: select "Show All" and examine each image object. Tools > Print Production > PDF Optimizer > Audit Space Usage shows what proportion of file size is consumed by images. Extracting with PyMuPDF: import fitz doc = fitz.open("document.pdf") for page in doc: for img in page.get_images(): xref = img[0] base = doc.extract_image(xref) print(base["width"], base["height"], base["colorspace"], base["ext"]) Identifying oversized images — A common optimisation target is images with much higher resolution than needed for the intended output. A 600 DPI image in a screen-only PDF is twice the necessary resolution — compressing it to 300 DPI would halve the image data size. The pdfimages -list output shows each image's DPI relative to its on-page size, making over-resolution easy to identify. Image recompression — Ghostscript can recompress images in a PDF with different filter parameters: gs -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -dPDFSETTINGS=/ebook -sOutputFile=compressed.pdf input.pdf The /ebook setting applies JPEG at quality ~75 and downsamples to 150 DPI. For more control, use a PDF optimizer (iText PdfWriter with PdfPageFormXObjectConvertAction, or Acrobat Pro PDF Optimizer).