PNG compression does not depend solely on the characteristics of the input file. In fact, results can be various, and best settings for an image is not an easy thing to find. In a first time, we've to define what is optimization
, compression
, lossless
and lossy
.
Optimizationrepresents all steps before compression. The goal here is to choose best settings for an high compression ratio. Factors are ColorType, Delta Filtering, BitDepth and Transparency Methods.
Compressionis the next step. Filtered codes are compressed in LZ77 codes, that are further compressed by the Huffman algorithm (this is also called the
Deflatealgorithm).
Losslesscan mean
without loss in every level. Here, it's used as
lossless for Web; the output file is identique as the original, when it's displayed by a Web Browser.
Lossymean the input image file is different when it's displayed by a Web Browser. Most of case, it's cause to the number of colors -less colors than the original-.
| GrayScale | TrueColor | Paletted | GrayScale+Alpha | TrueColor+Alpha |
![]() |
![]() |
![]() |
![]() |
![]() |
| No Filter | Sub | Up | Average | Paeth |
![]() |
![]() |
![]() |
![]() |
![]() |
| Bit(s) Per Pixel | 1 | 2 | 4 | 8 | 16 | 24 | 32 |
| Samples | |||||||
| Colors | 1 or 2 | 3 or 4 | 5 to 16 | 17 to 256 | 1 to 256 | 1 to 16277216 | 1 to 16277216 |
| ColorType | GrayScale or Paletted | GrayScale + Alpha | TrueColor | TrueColor + Alpha | |||
| GrayScale tRNS | Paletted tRNS (binary) | Paletted tRNS (alpha values) | TrueColor tRNS | GrayScale+Alpha | TrueColor+Alpha |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
An Image Reduction
is NOT a Conversion
: this is a lossless procedure. That's consist to choose the correct output settings for an image, without any restitution modifications : the image is restitued as the original, pixel-by-pixel. Conversion
is an User choice, consisting most of time in modification of number of colors.
Delete All unnecessary chunks which are not displayed to the user. Avoid any Color / Brightness correction, because Browser have also corrections settings which can be modified by user.
![]() |
![]() |
| Require Chunks | Unnecessary Chunks |
| 17549 Bytes | 23888 Bytes |
| Delete All unnecessary Chunks | |
Do not create more than 1 iDAT chunk for your PNG File. Always compact all iDAT chunk to one to save CRC bits-checks.
![]() |
![]() |
| 1 iDAT Chunk | More than 1 iDAT Chunk |
| 17549 Bytes | 20681 Bytes |
| Always Compact to One iDAT Chunk | |
For PNG8 (PNG Paletted), PNG's palette size is determined by the chunk size. Each entry of the palette require 3 Bytes ; counting colors is an excellent way to determine the number of entries are really necessary.
![]() |
![]() |
| 64 colors, 256 entries | 64 colors, 64 entries |
| 11419 Bytes | 10843 Bytes |
| Always count colors. Truncate the palette for optimal storage | |
For PNG Paletted (PNG8), you can use 1,2,4 or 8 bits/pixel. Count colors, and try to adapt the bitdepth with number of colors. There is also an exception : sometimes 8 bits/pixel is better, whereas 4 bits/pixel sould be.
![]() |
![]() |
| 8 colors, 8 bits/pixels | 8 colors, 4 bits/pixels |
| 427 Bytes | 389 Bytes |
| Choose Correct BitDepth for Paletted Images | |
![]() |
![]() |
| 4 colors, 2 bits/pixels | 4 colors, 8 bits/pixels |
| 3572 Bytes | 3296 Bytes |
| Test 8 bits/pixel for Paletted Images | |
When PNG8 use transparency, always sort the palette with the tRNS values on the first entries. You could save Bytes by deleting some Null-Alpha values.
![]() |
![]() |
| Null Alpha values | 1 Alpha value |
| 14068 Bytes | 13597 Bytes |
| Always rewrite the palette with tRNS first | |
When you convert an image to PNG8 (or operate quantization), duplicate entries can be present in the palette. You can gain few Bytes (just bytes entries) if you unify the entries.
![]() |
![]() |
| 16 entries, 5 useful colors | 5 entries, 5 useful colors |
| 1942 Bytes | 1907 Bytes |
| Always delete duplicate entries | |
Try to find the smallest path possible from PLTE to iDAT RGB values. Optimizing a palette could you let to optimize PNG further.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Organization 1 | Organization 2 | Organization 3 |
| 17549 Bytes | 16288 Bytes | 15907 Bytes |
| Try to find the Best Palette Optimization | ||
See more about PNG Palette Optimization.
When image contains less or equal to 256 colors, you should try to encode it to Paletted (for Color based) or GrayScale (Gray-Level based). Output size difference is often appreciable.
![]() |
![]() |
| 256 colors, TrueColor | 256 colors, Paletted |
| 38603 Bytes | 17549 Bytes |
| Choose the correct ColorType Output | |
Even if an image contains 256 colors or less, try to code it to GrayScale (if Gray-Level Colors) or TrueColor. Sometimes, it lets to delete pLTE chunk for a better storage.
![]() |
![]() |
| 256 colors, Paletted | 256 colors, TrueColor |
| 1057 Bytes | 441 Bytes |
If Colors can be filtered, try TrueColor even if it contains less than 256 colors |
|
If the image contains only Gray-Level colors, try to encode the image to GrayScale. It can sometimes gives best results for most of cases -if GrayScale type is a true GrayScale-.
![]() |
![]() |
| 256 colors, Paletted | 256 colors, GrayScale |
| 18680 Bytes | 15655 Bytes |
| If R,G and B values are identique for all entries, try to code to GrayScale | |
Sometimes, even if all colors are Gray-Level, Paletted just do it better than GrayScale. Do not forget to try Paletted, even if input is already GrayScale.
![]() |
![]() |
| 128 colors, GrayScale | 128 colors, Paletted |
| 15443 Bytes | 14434 Bytes |
| Try Paletted Instead Of GrayScale | |
If used colors are Gray-Level, try to encode a RGB+Alpha to GrayScale+Alpha when it's applicable. You save lot of bytes doing that.
![]() |
![]() |
| RGB+Alpha | GrayScale+Alpha |
| 36842 Bytes | 27014 Bytes |
| Use GrayScale+Alpha when applicable | |
If PNG is using an Alpha Channel, check if it can be reduced to TrueColor. TrueColor supports tRNS chunk, which can be used to set a binary
transparency.
![]() |
![]() |
| RGB+Alpha | RGB tRNS |
| 15489 Bytes | 8865 Bytes |
| Check Alpha Channel usage for TrueColor+Alpha | |
If PNG is using an Alpha Channel, check if it can be reduced to GrayScale. GrayScale supports tRNS chunk, which can be used to set a binary
transparency.
![]() |
![]() |
| GrayScale+Alpha | GrayScale tRNS |
| 6201 Bytes | 3503 Bytes |
| Check Alpha Channel usage for GrayScale+Alpha | |
If PNG is using an Alpha Channel and contains less or equal to 256 colors, check if it can be reduced to Paletted. Paletted can use Alpha values in pLTE chunk, which can have 0 to 255 opacity output.
Please note this demonstration is NOT a conversion. The original file is identique as the reduced
file : both of files contains 256 colors, and transparency is applied with a different but losslessly method.
![]() |
![]() |
| RGB+Alpha | Paletted tRNS |
| 25971 Bytes | 19426 Bytes |
| Check Alpha Channel usage for image which contains 256 colors or less | |
This is also applicable when input image is GrayScale+Alpha.
![]() |
![]() |
| GrayScale+Alpha | Paletted |
| 15067 Bytes | 13245 Bytes |
| Check Alpha Channel usage for image which contains 256 colors or less | |
Sure, number of image reduction are undeterminate. There are lot of possible combinaisons, you've to try yourself. The best way to find the correct output settings is just to test everything.
For a Web usage, there are others optimization settings. This one is efficient on RGB+Alpha or GrayScale+Alpha file. It can optimize the output file, by optimizing the transparency strategy. Please note this operation is lossless for Web, because browser display the input PNG File as the output PNG file. However, the RGB data stream is modified.
Sometimes, in an Alpha Channel, we can find alpha values which are 0. 0 is meaning the superposed
pixel in the RGB data is not displayed. If it's not displayed, we can check if we can optimize it further.
| The Original File | ||
![]() |
![]() |
![]() |
| Displayed PNG | RGB Channel | Alpha Channel |
| 31602 Bytes | - | - |
First trial available, you can just clean
the output file, by deleting all RGB data which have an 0
Alpha value in the Alpha Channel. Result :
| Clean all RGB data which are not Displayed | ||
![]() |
![]() |
![]() |
| Displayed PNG | RGB Channel | Alpha Channel |
| 30012 Bytes | - | - |
Second trial, you can apply a filter to the RGB data. In fact, filtered restitution is stored in RGB data. This technique can let you to squeeze much bytes.
| Extend pixel in the RGB area | ||
![]() |
![]() |
![]() |
| Displayed PNG | RGB Channel | Alpha Channel |
| 29008 Bytes | - | - |
See also : How to Optimize PNG Transparency.