Skip to content

A comparison of several state-of-the art lossless image compression formats.

License

Notifications You must be signed in to change notification settings

WangXuan95/Image-Compression-Benchmark

Repository files navigation

Lossless Image Compression Benchmark

This repo shows the performance of several state-of-the-art lossless image compression formats when compressing RGB 24-bit and Gray 8-bit images. Inspired by LPCB authored by Alex Rhatushnyak , but use a larger dataset, and provides a convenient Python script to run the benchmark.

Compress formats: See README_FormatList.md .

Test Environment: Intel Core i7 12700H, 16GB DDR4 in 3200MHz, Windows 10 system.

 

RGB 24-bit result

Benchmark dataset : 585 .pnm uncompressed RGB 24-bit image files, totaling 4 GB.

Note: All following results are strictly lossless compression.

Compressed            | Compressed size    |   Compression   |   Decompression  |  Command line                                                              | Command line                                    | Test
format/config         | bytes       ratio% |   time, seconds |   time, seconds  |  to compress                                                               | to decompress                                   | Environment
----------------------|--------------------|-----------------|------------------|----------------------------------------------------------------------------|-------------------------------------------------|-----------------
BMF     (-s)          | 1237071108  30.23% |    3101.102     |    2705.834      |  bmf.exe -s -Oout in.pnm                                                   | bmf.exe -pnm -Oout in.bmf                       | Win_x64
Gralic                | 1251405148  30.58% |     969.423     |    1109.887      |  Gralic111d.exe c out.gralic in.pnm                                        | Gralic111d.exe d in.gralic out.pnm              | Win_x64
LEA                   | 1289467320  31.51% |     419.658     |     481.112      |  LEA.exe in.pnm out.lea                                                    | LEA.exe in.lea out.pnm                          | Win_x64
NBLI    (-ga)         | 1311265320  32.05% |    2695.927     |    2536.709      |  NBLI.exe -fga in.pnm -o out.nbli                                          | NBLI.exe  -f in.nbli out.pnm                    | Win_x64
NBLI    (-g)          | 1326544840  32.42% |     277.564     |     240.414      |  NBLI.exe -fg  in.pnm -o out.nbli                                          | NBLI.exe  -f in.nbli out.pnm                    | Win_x64
JPEG-XL (-q 100 -e 8) | 1328936777  32.48% |    6936.972     |     278.855      |  cjxl.exe in.pnm out.jxl -q 100 -e 8 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
NBLI                  | 1331656642  32.54% |     201.997     |     167.425      |  NBLI.exe -f   in.pnm -o out.nbli                                          | NBLI.exe  -f in.nbli out.pnm                    | Win_x64
FLIC                  | 1332363598  32.56% |     128.098     |     150.450      |  FLIC.exe c out.flic in.pnm                                                | FLIC.exe d in.flic out.pnm                      | Win_x64
JPEG-XL (-q 100 -e 7) | 1337119292  32.68% |    2684.973     |     249.359      |  cjxl.exe in.pnm out.jxl -q 100 -e 7 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
fNBLI                 | 1337587020  32.69% |      43.164     |      27.450      |  fNBLI.exe -f in.pnm -o out.fnbli                                          | fNBLI.exe -f in.fnbli out.pnm                   | Win_x64
JPEG-XL (-q 100 -e 6) | 1359767682  33.23% |    1728.935     |     214.077      |  cjxl.exe in.pnm out.jxl -q 100 -e 6 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 5) | 1373095937  33.56% |    1099.045     |     192.344      |  cjxl.exe in.pnm out.jxl -q 100 -e 5 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 4) | 1385013285  33.85% |     567.416     |     165.030      |  cjxl.exe in.pnm out.jxl -q 100 -e 4 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
BMF                   | 1389521424  33.96% |     201.699     |     158.537      |  bmf.exe -Oout in.pnm                                                      | bmf.exe -pnm -Oout in.bmf                       | Win_x64
JPEG-XL (-q 100 -e 3) | 1399673135  34.21% |     213.004     |     146.406      |  cjxl.exe in.pnm out.jxl -q 100 -e 3 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
QLIC2                 | 1461101919  35.71% |      29.899     |      30.152      |  FLIC.exe c out.flic in.pnm                                                | FLIC.exe d in.flic out.pnm                      | Win_x64
BIM                   | 1472723769  35.99% |     187.279     |     211.560      |  FLIC.exe c out.flic in.pnm                                                | FLIC.exe d in.flic out.pnm                      | Win_x64
HALIC                 | 1473481803  36.01% |      22.187     |      28.447      |  HALIC072e.exe in.pnm out                                                  | HALIC072d.exe in out.pnm                        | Win_x64
WEBP    (lossless m5) | 1475908700  36.07% |    1112.134     |      49.442      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=5)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
WEBP    (lossless m4) | 1485394588  36.30% |     912.204     |      48.791      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=4)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
WEBP    (lossless m1) | 1496478650  36.57% |     720.160     |      37.044      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=1)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
HALICfast             | 1537725512  37.58% |      19.112     |      23.784      |  HALIC072e.exe in.pnm out                                                  | HALIC072d.exe in out.pnm                        | Win_x64
JPEG-XL (-q 100 -e 2) | 1547272952  37.81% |     116.894     |      64.679      |  cjxl.exe in.pnm out.jxl -q 100 -e 2 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 1) | 1648242164  40.28% |      42.993     |      57.650      |  cjxl.exe in.pnm out.jxl -q 100 -e 2 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
QIC                   | 1699046729  41.52% |      19.942     |      20.639      |  FLIC.exe c out.flic in.pnm                                                | FLIC.exe d in.flic out.pnm                      | Win_x64
PNG     (optipng -o5) | 1899273578  46.42% |   27680.424     |      25.799      |  optipng.exe -o5 -force in.pnm -out out.png                                | Image.open('in.png').save('out.pnm')            | Win_x64
PNG     (optipng -o2) | 1905215734  46.56% |    4395.069     |      26.625      |  optipng.exe -o2 -force in.pnm -out out.png                                | Image.open('in.png').save('out.pnm')            | Win_x64
JPEG-LS               | 1931584595  47.21% |      72.237     |      66.567      |  Image.open('in.pnm').save('out.jls',spiff=None)                           | Image.open('in.jls').save('out.pnm')            | Python Pillow
PNG  (optimize=True)  | 1935713540  47.31% |    1120.213     |      28.635      |  Image.open('in.pnm').save('out.png', optimize=True)                       | Image.open('in.png').save('out.pnm')            | Python Pillow
JPEG2000              | 1992860964  48.70% |     319.912     |     275.398      |  Image.open('in.pnm').save('out.j2k',format='JPEG2000',irreversible=False) | Image.open('in.j2k').save('out.pnm')            | Python Pillow
PNG  (optimize=False) | 2003016524  48.95% |     334.791     |      33.677      |  Image.open('in.pnm').save('out.png', optimize=False)                      | Image.open('in.png').save('out.pnm')            | Python Pillow
QOI                   | 2280217586  55.73% |      19.061     |      18.970      |  Image.open('in.pnm').save('out.j2k',format='JPEG2000',irreversible=False) | Image.open('in.j2k').save('out.pnm')            | Python Pillow
(uncompressed)        | 4091841959  100.0% |                 |                  |                                                                            |                                                 |
rgb24
Figure: benchmark result of RGB 24-bit image compression

 

 

Gray 8-bit Result

Benchmark dataset : 64 .pnm uncompressed Gray 8-bit image files, totaling 751 MB.

Note: All following results are strictly lossless compression.

Compressed            | Compressed size    |   Compression   |   Decompression  |  Command line                                                              | Command line                                    | Test
format/config         | bytes       ratio% |   time, seconds |   time, seconds  |  to compress                                                               | to decompress                                   | Environment
----------------------|--------------------|-----------------|------------------|----------------------------------------------------------------------------|-------------------------------------------------|-----------------
BMF     (-s -q9)      | 261105188   34.75% |     722.372     |     228.101      |  bmf.exe -s -q9 -Oout in.pnm                                               | bmf.exe -pnm -Oout in.bmf                       | Win_x64
BMF     (-s)          | 261261936   34.77% |     258.793     |     233.820      |  bmf.exe -s -Oout in.pnm                                                   | bmf.exe -pnm -Oout in.bmf                       | Win_x64
MRP     (-o)          | 262448355   34.93% |  549043.153     |      80.030      |  mrp_enc.exe -o in.pnm out.mrp                                             | mrp_dec.exe in.mrp out.pnm                      | Win_x64
MRP                   | 263367040   35.04% |  106752.508     |      81.212      |  mrp_enc.exe    in.pnm out.mrp                                             | mrp_dec.exe in.mrp out.pnm                      | Win_x64
JPEG-XL (-q 100 -e 9) | 270223280   35.96% |    5496.322     |      46.113      |  cjxl.exe in.pnm out.jxl -q 100 -e 9 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 8) | 270779849   36.04% |    1140.146     |      45.280      |  cjxl.exe in.pnm out.jxl -q 100 -e 8 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
NBLI    (-ga)         | 270923880   36.06% |     493.668     |     484.695      |  NBLI.exe -fga in.pnm -o out.nbli                                          | NBLI.exe  -f in.nbli out.pnm                    | Win_x64
JPEG-XL (-q 100 -e 7) | 271563265   36.14% |     584.105     |      53.102      |  cjxl.exe in.pnm out.jxl -q 100 -e 7 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
NBLI                  | 274365390   36.51% |      38.801     |      31.061      |  NBLI.exe  -f in.pnm -o out.nbli                                           | NBLI.exe  -f in.nbli out.pnm                    | Win_x64
fNBLI                 | 275023238   36.60% |       7.481     |       4.622      |  fNBLI.exe -f in.pnm -o out.fnbli                                          | fNBLI.exe -f in.fnbli out.pnm                   | Win_x64
CALIC                 | 275071904   36.61% |     136.689     |     132.305      |  calic8e.exe in.raw (width) (height) 8 0 out.calic                         | calic8d.exe in.calic out.raw                    | Win_x64
JPEG-XL (-q 100 -e 6) | 276150100   36.75% |     378.297     |      48.910      |  cjxl.exe in.pnm out.jxl -q 100 -e 6 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-LS_extension     | 276832963   36.84% |      91.660     |      83.642      |  JLSx.exe in.pnm out.jlsxn                                                 | JLSxn.exe in.jlsxn out.pnm                      | Win_x64
JPEG-XL (-q 100 -e 5) | 277648911   36.95% |     235.240     |      39.003      |  cjxl.exe in.pnm out.jxl -q 100 -e 5 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 4) | 279689490   37.22% |     100.596     |      30.338      |  cjxl.exe in.pnm out.jxl -q 100 -e 4 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG-XL (-q 100 -e 3) | 279843069   37.24% |      41.997     |      27.439      |  cjxl.exe in.pnm out.jxl -q 100 -e 3 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
BMF                   | 281729564   37.49% |      27.015     |      26.590      |  bmf.exe -Oout in.pnm                                                      | bmf.exe -pnm -Oout in.bmf                       | Win_x64
JPEG-LS               | 284310637   37.84% |      13.719     |      12.316      |  Image.open('in.pnm').save('out.jls',spiff=None)                           | Image.open('in.jls').save('out.pnm')            | Python Pillow
JPEG-LS               | 284310637   37.84% |      18.460     |      18.813      |  JPEGLSenc.exe in.pnm -oout                                                | JPEGLSdec.exe in out.pnm                        | Win_x64
WEBP    (lossless m6) | 289966290   38.59% |    3460.702     |      10.958      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=6)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
WEBP    (lossless m5) | 289982418   38.59% |     368.948     |      11.102      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=5)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
HALIC                 | 290744703   38.69% |       2.429     |       3.116      |  HALIC072e.exe in.pnm out                                                  | HALIC072d.exe in out.pnm                        | Win_x64
WEBP    (lossless m4) | 291450516   38.79% |     333.802     |      10.727      |  Image.open('in.pnm').save('out.webp',lossless=True,quality=100,method=4)  | Image.open('in.webp').save('out.pnm')           | Python Pillow
JPEG-XL (-q 100 -e 2) | 293929577   39.12% |      23.874     |      10.844      |  cjxl.exe in.pnm out.jxl -q 100 -e 2 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
JPEG2000              | 294836093   39.24% |      44.764     |      37.418      |  Image.open('in.pnm').save('out.j2k',format='JPEG2000',irreversible=False) | Image.open('in.j2k').save('out.pnm')            | Python Pillow
HALICfast             | 298660889   39.75% |       1.809     |       2.493      |  HALIC072fe.exe in.pnm out                                                 | HALIC072fd.exe in out.pnm                       | Win_x64
BPG/HEVC              | 303248314   40.36% |    2119.629     |     184.144      |  bpgenc.exe -lossless -e jctvc -m1 -o out.bpg in.png                       | bpgdec.exe -o out.png in.bpg                    | Win_x64
PNG     (optipng -o7) | 303703031   40.42% |   17779.304     |       6.798      |  optipng.exe -o7 -force in.pnm -out out.png                                | Image.open('in.png').save('out.pnm')            | Win_x64
PNG     (optipng -o5) | 303703031   40.42% |    6603.849     |       6.618      |  optipng.exe -o5 -force in.pnm -out out.png                                | Image.open('in.png').save('out.pnm')            | Win_x64
PNG     (optipng -o2) | 304379777   40.51% |    1028.626     |       6.682      |  optipng.exe -o2 -force in.pnm -out out.png                                | Image.open('in.png').save('out.pnm')            | Win_x64
JPEG-XL (-q 100 -e 1) | 316257036   42.09% |      13.680     |      12.523      |  cjxl.exe in.pnm out.jxl -q 100 -e 1 --quiet --num_threads=0               | djxl.exe in.jxl out.pnm --quiet --num_threads=0 | Win_x64
PNG  (optimize=True)  | 318912342   42.44% |     290.616     |       6.702      |  Image.open('in.pnm').save('out.png', optimize=True)                       | Image.open('in.png').save('out.pnm')            | Python Pillow
PNG  (optimize=False) | 324246297   43.15% |      98.715     |       7.171      |  Image.open('in.pnm').save('out.png', optimize=False)                      | Image.open('in.png').save('out.pnm')            | Python Pillow
XZ      (-9 --extreme)| 378068772   50.31% |     422.718     |      36.415      |  xz -zk -9 --extreme in.pnm                                                | xz -dk in.pnm.xz                                | Linux x64 (WSL)
Gzip    (-9)          | 459102381   61.40% |      74.900     |      13.929      |  gzip -k -9 in.pnm                                                         | gzip -dk in.pnm.gz                              | Linux x64 (WSL)
(uncompressed)        | 751411774   100.0% |                 |                  |                                                                            |                                                 |
gray8
Figure: benchmark result of Gray 8-bit image compression