PNG
37c3317fd058; modified for Encode Wiki · CC BY-SA 4.0PNG (1996) is the lossless format for screenshots, UI, diagrams, pixel art and anything that needs real transparency. It was created as a patent-free replacement for GIF, and the third edition of the spec (a W3C Recommendation since June 2025) adds animation (APNG), HDR colour signalling (cICP, mDCV, cLLI) and Exif.
| Property | Value |
|---|---|
| Compression | Lossless (per-row filters plus DEFLATE) |
| Bit depth | 1, 2, 4, 8 or 16 bits per sample (palette up to 8 bits) |
| Colour types | Grayscale, RGB, indexed palette, with or without alpha |
| Alpha | Full alpha channel, or per-entry alpha in palette images |
| Animation | APNG, supported by all current browsers |
| Progressive | Adam7 interlacing (usually makes files larger) |
| Royalty-free | Yes |
When to use it
Section titled “When to use it”- Use PNG for screenshots, graphics with flat colour or sharp edges, masters you will edit again, and anything that must come out pixel-exact.
- Not for photos. A photo as PNG is several times larger than a good JPEG, and usually larger than lossless WebP or lossless JPEG XL too. Use JPEG, AVIF or WebP for delivery.
- For smaller PNGs, you have two routes: lossless recompression (oxipng, ECT) which never changes pixels, or palette quantisation (pngquant) which does and often saves 60–80%.
Shrink PNGs without changing pixels
Section titled “Shrink PNGs without changing pixels”oxipng
Section titled “oxipng”oxipng is the usual choice: multithreaded, fast, and able to do limited optimisation of APNG. It rewrites files in place unless you give --out or --dir.
oxipng -o 4 --strip safe image.png --out image.opt.pngoxipng -o max --strip safe *.png| Option | What it does |
|---|---|
-o 0…-o 6, -o max | Effort. Default is 2, which is fast and already good; higher levels have diminishing returns. max is level 6. |
--strip safe (-s) | Removes non-critical chunks but keeps cICP, iCCP, sRGB, pHYs and the APNG chunks. Use --strip all only if you are sure no colour or animation data matters. |
--alpha (-a) | Rewrites the colour of fully transparent pixels to compress better. Looks identical, but the hidden RGB values change. |
-z | Uses Zopfli instead of libdeflate. Slower, small extra gain. |
--scale16 | Converts 16-bit to 8-bit. Lossy; oxipng otherwise keeps 16-bit data intact. |
Without --strip oxipng keeps every chunk that is still valid, including metadata.
Efficient Compression Tool (ect) optimises PNG and JPEG (and gzip/zip) in place. Level -9 is very slow; -3 is the default.
ect -9 -strip image.pngect also recompresses JPEGs losslessly (-progressive makes them progressive). ZopfliPNG and OptiPNG do the same job; OptiPNG is the older tool, ZopfliPNG strips all ancillary chunks (including colour profiles) unless told to keep them.
Shrink PNGs by reducing colours (lossy)
Section titled “Shrink PNGs by reducing colours (lossy)”pngquant converts RGB/RGBA to an 8-bit palette with per-colour alpha, using dithering to hide the loss. It suits icons, illustrations and screenshots; smooth gradients and photos can band or posterise.
pngquant --quality 65-90 --skip-if-larger --strip --output small.png input.png--quality min-maxpicks the fewest colours that reachmax; if it cannot reachminit writes nothing and exits with status 99 (98 for--skip-if-larger).--speedruns 1 (slowest, best) to 11. The default is 4 and the author recommends leaving it unless you need real-time speed.--nofsturns off dithering (cleaner flat areas, more banding in gradients).--floyd=0.5reduces it.--ext .png --forceoverwrites input files in place. There is no backup.
Run oxipng on the result for a little more.
Pitfalls
Section titled “Pitfalls”- Metadata and colour: PNG colour can come from
sRGB,iCCP,cICP, or legacygAMA/cHRM. oxipng’s--strip safedropsgAMAandcHRM, and--strip alldrops everything non-critical, so check images that depended on them. Missing profiles change how colour-managed viewers show the image. - Interlacing: Adam7 costs compression and is rarely worth it. oxipng removes it by default; use
-i keepor-i onif you need it. - Hidden RGB in transparent pixels:
--alphaand ZopfliPNG’s--lossy_transparentchange it. Harmless for display, wrong if the same file feeds a later edit or a texture pipeline. - 16-bit images: many tools silently convert to 8-bit. Keep an eye on
--scale16, ImageMagick’s-depth 8and any “web export” preset. - APNG: only some tools keep every frame.
oxipng --strip allandoptipng -snipflatten animations. For animation that is not a looping sticker, an actual video or animated WebP/AVIF is far smaller. - Large flat-colour screenshots may compress better as lossless WebP or JPEG XL if the destination supports them.
Full option reference
Section titled “Full option reference”Every option and default for oxipng 10.2.1, OptiPNG 7.9.1, pngquant 3.0.3 and ZopfliPNG. Reading option tables explains the Default column.
oxipng parameter reference
Section titled “oxipng parameter reference”Use -- before an input filename that begins with a hyphen. The hidden -Z is still accepted as an alias of --zopfli.
Complete oxipng 10.2.1 options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
--opt, -o | enum 0–6/max | 2 | Preset from 0 (fastest) to 6 or max (smallest); explicit coding options override it. |
--recursive, -r | switch | off | Optimizes every .png and .apng file found in input directories. |
--dir | directory | not specified | Writes outputs into this directory, creating it; recursion flattens the folder layout. |
--out | path | not specified (input replaced if optimized) | Writes the result to this file instead of replacing the input. |
--stdout | switch | off | Writes the PNG to stdout; cannot combine with —dir, —out or —json. |
--preserve, -p | switch | off | Keeps the original permissions and timestamps where possible. |
--dry-run, -d | switch | off | Reports the savings without writing any file. |
-s | switch | off | Same as —strip safe: removes non-essential chunks and keeps those that affect display. |
--strip | mode/list | keep valid chunks, except caBX/iDOT | safe, all or a comma-separated chunk list; all also turns APNG into a plain PNG. |
--keep | comma-separated chunk names | not specified | Strips everything except the listed chunks; display keeps the appearance-affecting set. |
--alpha, -a | switch | off | Rewrites colour values of fully transparent pixels to compress better; visually lossless. |
--interlace, -i | enum | off; keep with —nx | off, on (Adam7) or keep; interlacing adds 25–50% to the size. |
--scale16 | switch | off | Reduces 16-bit channels to 8-bit by scaling; lossy. |
--verbose, -v | repeatable switch | 0 occurrences | Shows per-file detail; repeat for more. Cannot combine with —quiet. |
--quiet, -q | switch | off | Suppresses all output. |
--json, -j | switch | off | Prints results as JSON; cannot combine with —stdout. |
--filters, -f | integer list/range 0–9 | 0,1,6,7 at level 2 | Row filters to try: 0–4 fixed, 5 MinSum, 6 Entropy, 7 Bigrams, 8 BigEnt, 9 Brute. |
--fast | switch | on at levels 0–4; off at 5–6 | Scores filters with a quick pass, then runs one full trial on the best. |
--zc | integer 0–12 | 11 at level 2 | libdeflate level 0–12 for main trials; cannot combine with —zopfli. |
--nb | switch | off | Keeps the original bit depth. |
--nc | switch | off | Keeps the original colour type. |
--np | switch | off | Does not convert to indexed colour or change an existing palette. |
--ng | switch | off | Does not convert to or from greyscale. |
--nx | switch | off | Disables every reduction and makes the default interlace mode keep. |
--nz | switch | off | Skips IDAT recompression unless a transformation needs it; with —nx, disables all optimization. |
--fix | switch | off | Skips chunk checksum validation so damaged files can be processed; output checksums are valid. |
--force | switch | off | Writes the output even when it is larger than the input. |
--zopfli, -z, -Z | switch | off | Uses Zopfli instead of libdeflate for main trials; much slower, a little smaller. |
--zi | positive u64 | 15 | Zopfli iteration count; fewer is faster. Requires —zopfli. |
--ziwi | positive u64 | not specified | Stops Zopfli after this many iterations without improvement; pair with a high —zi. |
--brute-level | integer 1–12 | 1; 5 at level 6 | libdeflate level for the Brute filter; 1–5 is sensible. |
--brute-lines | nonnegative integer | 3; 4 at level 4; 8 at levels 5–6 | Rows compressed together by the Brute filter; 2–16 is sensible. |
--timeout | u64 seconds | no limit | Time budget in seconds, checked between trials; a running trial can overrun it. |
--max-raw-size | size with unit suffix | no limit | Skips images whose decompressed data exceeds this size; accepts suffixes like k or MB. |
--threads, -t | nonnegative integer | logical CPU count | Maximum worker threads; 0 lets Rayon choose. |
--sequential | switch | off (parallel file processing) | Processes files one at a time, in order. |
--help, -h | action | not requested | Shows help. |
--version, -V | action | not requested | Prints the version. |
-- | action | not requested | Ends option parsing so later arguments are input paths. |
Presets: -o 0 uses filters 0,5 with libdeflate level 5; -o 1 uses 0,7 and level 10; -o 2 (default) uses 0,1,6,7 and level 11 with fast evaluation; -o 3 adds filters 8,9; -o 4 uses level 12; -o 5 and -o 6 disable fast evaluation, -o 6 uses every filter. Explicit --filters, --zc, --brute-* and --fast options override the preset regardless of order.
--strip safe / --keep display keep cICP, iCCP, sRGB, pHYs, acTL, fcTL and fdAT, and drop other ancillary chunks such as gAMA, cHRM, sBIT, mDCV and cLLI. Without --strip, oxipng keeps every chunk that is still valid, but drops caBX and Apple iDOT.
OptiPNG parameter reference
Section titled “OptiPNG parameter reference”OptiPNG takes the same kind of optimisation switches but uses single-hyphen options, and documented prefixes are accepted as abbreviations. Prefer the full lowercase spelling. Attached forms such as -o2, -f0,5 and -zc9 are the same options.
Complete OptiPNG 7.9.1 options, aliases, and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
-o | nonnegative integer | 2 | Preset 0–7, higher is slower and smaller; larger values act as 7. |
-out, -ou | path | not specified (input can be replaced) | Output file for a single input; cannot combine with -dir. |
-dir, -d, -di | directory | not specified | Output directory; cannot combine with -out. |
-backup, -b, -ba, -bac, -back, -backu, -keep, -k, -ke, -kee | switch | off | Keeps a .bak copy when overwriting the input. |
-clobber, -c, -cl, -clo, -clob, -clobb, -clobbe | switch | off | Allows replacing an existing output file. |
-fix, -fi | switch | off | Tries to recover malformed input; check the result. |
-force, -fo, -for, -forc | switch | off | Writes an output file even when no improvement is found. |
-preserve, -p, -pr, -pre, -pres, -prese, -preser, -preserv | switch | off | Keeps file attributes such as permissions and timestamps where possible. |
-quiet, -q, -qu, -qui, -quie, -silent, -sil, -sile, -silen | switch | off | Suppresses normal output. |
-simulate, -sim, -simu, -simul, -simula, -simulat | switch | off | Runs the optimization without writing files. |
-f | set/ranges 0–5 | 0,5 at level 2 | Row filters to try: 0–4 fixed, 5 adaptive. Accepts lists and ranges such as 0,5. |
-i | integer 0–1 | retain input interlace | Output interlacing: 0 none, 1 Adam7. |
-zc | set/ranges 1–9 | 9 at level 2 | zlib compression levels to try, 1–9. |
-zm | set/ranges 1–9 | 8 at level 2 | zlib memory levels to try, 1–9. |
-zs | set/ranges 0–3 | 0–3 at level 2 | zlib strategies to try: 0 default, 1 filtered, 2 Huffman-only, 3 RLE. |
-zw | power-of-two size | libpng default 32 KiB; smaller for Huffman/RLE | zlib window size, 256 to 32768 bytes; accepts suffixes like 4k. |
-full, -fu, -ful | switch | off | Produces a full IDAT report, which can slow the search. |
-nb | switch | off | Disables bit-depth reduction. |
-nc | switch | off | Disables colour-type reduction. |
-np | switch | off | Disables palette reduction. |
-nx | switch | off | Disables all three reductions. |
-nz | switch | off | Skips IDAT recompression unless a reduction needs it. |
-snip, -sn, -sni | switch | off | Extracts one image from an animated or multi-image file and drops the rest. |
-strip, -st, -str, -stri | object | not enabled | Only all is accepted; individual chunks cannot be named. |
-v | switch | off | Verbose output; with no input files, prints the version and copyright. |
-verbose, -verb, -verbo, -verbos | switch | off | Verbose output only. |
-version, -vers, -versi, -versio | action | not requested | Prints the version when no input files are given. |
-debug | switch | off | Enables internal debug features; cannot be abbreviated. |
-log, -lo | removed option | not supported | Removed; the parser rejects it. Redirect output with the shell instead. |
-help, -?, -h, -he, -hel | action | not requested | Shows extended help. |
-- | action | not requested | Ends option parsing so later arguments are input paths. |
The default -o2 searches -zc9 -zm8 -zs0-3 -f0,5. Higher levels search more combinations but never add visual loss. Repeated -f and -z* sets are unioned. -strip accepts only all. -snip extracts a single image from an animated or multi-image input and discards the animation. See the versioned manual.
pngquant parameter reference
Section titled “pngquant parameter reference”This is the Rust frontend (3.0.3). The optional positional ncolors is the same as the hidden --colors.
Complete pngquant 3.0.3 Rust options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
--colors | integer 2–256 | 256 maximum | Maximum palette size, 2–256; the positional ncolors argument sets the same limit. |
--quality, -Q | min-max in 0–100 | no minimum; target 100 | Quality range min-max, 0–100. Below min the image is refused (exit 99). A single N means 90% of N to N. |
--speed, -s | integer 1–11 | 4 | 1 (slowest, best) to 11 (fastest); 10 compresses the PNG faster, 11 also disables dithering. |
--floyd | optional float | 1 | Floyd–Steinberg dithering strength 0–1; write —floyd=0.5. |
--nofs, --ordered | switch | off | Disables dithering; —ordered is an alias. |
--posterize | integer 0–4 | 0 | Drops this many low bits of colour precision, 0–4; lossy but smaller. |
--strip | switch | off | Removes optional metadata chunks. |
--map | PNG path | not specified | Uses the colours of this PNG as a fixed palette. |
--ext | suffix | -fs8.png; -or8.png without dithering | Output filename suffix for batch runs; cannot combine with —output. |
--output, -o | path | derived suffix; stdout for stdin | Single output file; - writes to stdout. |
--force, -f | switch | off | Overwrites existing output files without a backup. |
--no-force | switch | off | Never overwrites existing files, even when —force is also given. |
--skip-if-larger | switch | off | Writes nothing when the result is not smaller than the input (exit 98). |
--transbug | switch | off | Puts a transparent entry last in the palette for old, buggy viewers. |
--iebug | ignored switch | off | Accepted but ignored in 3.0.3. |
--verbose, -v | switch | off | Prints status and quantization details. |
--quiet, -q | switch | off | Accepted but has no effect; output is already quiet unless —verbose is given. |
--help, -h | action | not requested | Shows help. |
--version, -V | action | not requested | Prints the version. |
-- | action | not requested | Ends option parsing so later arguments are the color count and input paths. |
--quality 65-85 tries a palette that meets 85 and refuses images that cannot reach 65, with exit code 99; 98 is the --skip-if-larger refusal. When reading from stdin the original may be passed through unchanged, so check what the pipeline actually produced. --iebug is registered but ignored in this version. The old C-only spellings (-nofs, -fs) are not accepted. --nofs and --ordered both mean no error diffusion.
ZopfliPNG parameter reference
Section titled “ZopfliPNG parameter reference”Pinned to Google’s source commit df1517dd8518 (30 September 2026); there is no versioned release. Long-option values are attached with =.
Complete pinned Google ZopfliPNG options and defaults
| Parameter and aliases | Type / accepted values | Default | Meaning and limits |
|---|---|---|---|
-m | repeatable switch | off (15/5 iterations) | Multiplies the iteration counts by 4; repeat for more. |
-y | switch | off | Overwrites existing output without asking; a smaller earlier output is still kept. |
-d | switch | off | Dry run: prints sizes without saving. |
-q | switch | off | Fast compression without Zopfli; for quickly trying filters and colour types. |
--prefix | optional text attached with = | not enabled; zopfli_ when bare | Batch mode: writes prefixed copies of each input, optionally into a directory. Use —prefix=name. |
--always_zopflify | switch | off | Writes the Zopfli output even when larger than the input; for benchmarking. |
--verbose | switch | off | Prints a detailed coding report. |
--lossy_transparent | switch | off | Discards RGB values behind fully transparent pixels. |
--lossy_8bit | switch | off | Converts 16-bit channels to 8-bit; lossy. |
--iterations | integer attached with = | 15 below 200000 raw bytes; 5 otherwise | Zopfli iterations for any file size; more is slower and slightly smaller. Minimum 1. |
--splitting | ignored compatibility argument | ignored | Ignored; kept for backward compatibility. |
--filters | characters attached with = | automatic fast selection | Strategies to try: 0–4 fixed, m MinSum, e entropy, p input filters, b brute force. 0me is a good set. |
--keepchunks | comma-separated four-letter chunk names | none (IHDR,PLTE,tRNS,IDAT,IEND only) | Extra chunks to keep, as exact four-letter names separated by commas (iCCP,gAMA). bKGD or sBIT also pins the colour type. |
--keepcolortype | switch | off | Keeps the input colour type and bit depth, at some cost in compression. |
--help, -h | action | not requested | Shows help. |
The default iteration split depends on the raw DEFLATE input size (15 below 200,000 bytes, otherwise 5). An existing output file is treated as a previous candidate and kept if smaller. ZopfliPNG returns success on some failure paths, so confirm the output exists and decodes. By default it keeps only IHDR, PLTE, tRNS, IDAT and IEND, which removes colour profiles; list the ones the image needs, such as --keepchunks=iCCP,sRGB,gAMA,cHRM,cICP; names are exact four-letter, case-sensitive and comma-separated with no spaces. It is not an APNG optimiser.