Skip to content


Switch branches/tags

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Perceptual Image Optimizer

Rust reuse compliant

pio is a command-line utility to compress image files while maintaining the same perceived quality. It's designed primarily to optimize photographs for the web.


  • Optimize images automatically for the web
  • Supports PNG, JPEG and WebP
  • Ensure images are displayed consistently across browsers by handling ICC profiles and Exif orientation
  • Powered by great projects like mozjpeg and pngquant
  • Easily installable statically-linked binary (for Linux and macOS)

pio is still under development but should be usable for most images. You can help by testing pio and giving feedback by GitHub issues.


Images are an important part of the web and make up a large part of the typical website (see HTTP Archive's Page Weight for statistics). Optimizing images can make websites faster to load and reduce the required bandwidth.

How much should you optimize images? Many image editors and optimization tools only give you parameters such as quality or file size. You could use the same parameters for each image. This will certainly optimize your images but may not be optimal for all images. You could also specify parameters by hand for each image but this isn't feasible if there are many images, or if images are uploaded by end users.

pio simplifies image optimization by finding optimal parameters automatically. This is done by optimizing the input image with different qualities and comparing structural similarity (SSIM).


Here we can see that pio finds different quality parameter for different images (using default settings). In general images with a lot of details require higher quality than those with fewer details.

However, pio is not perfect: for example some JPEG artifacts are visible in the first example image. In this case the quality setting is optimized for the solid sky covering most of the image but not the finer details of the bridge.

Original Optimized JPEG Optimized WebP

Photo: Josh Felise
CC0 1.0Source

File size: 2.1 KiB
Quality: 75

File size: 2.0 KiB
Quality: 83

Photo: Dominik Martin
CC0 1.0Source

File size: 5.5 KiB
Quality: 88

File size: 5.7 KiB
Quality: 89

Photo: Michael Day
CC0 1.0Source

File size: 21 KiB
Quality: 95

File size: 15 KiB
Quality: 81



Download the latest Linux binary from GitHub releases.

There are two versions: glibc and musl. glibc version is about 50% faster than musl version but may not work on old and non-glibc-based distributions. For reference, the glibc version is built on Ubuntu 18.04 against glibc 2.27.

After downloading the binary, run chmod +x path-to-pio to make it executable. Consider storing the binary somewhere on your PATH like /usr/local/bin/pio.


Download the latest macOS binary from GitHub releases.

After downloading the file, run chmod +x path-to-pio in your terminal to make it executable. Now try running ./path-to-pio --version.

If you get an error like "pio cannot be opened because the developer cannot be verified", open "System Preferences" section "Security & Privacy" tab "General" and click "Allow Anyway". Now you should be able to run pio. For more information, see Safely open apps on your Mac by Apple.

Building from source

Download source code from GitHub releases or clone this repository for development version. Compiling pio requires Rust and C toolchains. Run cargo build --release to build binary at target/release/pio.


Basic usage:

$ pio input.jpeg --output output.jpeg

The target quality can be set using --quality option:

$ pio input.jpeg --quality 95 --output output.jpeg

The target quality is a value between 0 and 100 and roughly corresponds to JPEG quality values.

For the full list of available options, run pio --help.

Input images

pio works by comparing the optimized image to the input image. The input image should preferably be PNG or lossless WebP, or alternatively JPEG or lossy WebP stored with a high quality setting (95-100). pio will make already lossy compressed images look worse.

For the web, the first and most important optimization is resizing images close to the size they're displayed at. For the best result, first resize a high-resolution source image and store the resulting image with lossless compression. Only after this, optimize the resized image with pio.

For example with the help of ImageMagick you could resize and optimize an image:

$ magick big.jpeg -resize 640x small.png
$ pio small.png --output optimized.jpeg

Most likely you also want to use responsive images where you create multiple differently sized images for different display resolutions. You should do the resizing and optimization for each size independently.

Quality setting explained

pio uses an internal table to map target --quality setting to SSIM value. This table has been calculated by running a corpus of images through JPEG encoder and calculating the average SSIM value for each JPEG quality setting.

This makes it possible to target the quality using a familiar 0-100 scale instead of a more obscure SSIM value.

pio sets the minimum and maximum quality automatically based on the --quality option. You can control the quality spread from the target using the --spread option. For example the following command:

$ pio input.jpeg --quality 80 --spread 10 --output output.jpeg

will target JPEG quality of 80 with the minimum quality of 70 and maximum quality of 90. The final quality setting will be selected by the SSIM calculation and it will depend on the complexity of the image.

If you need, you can override this automatic calculation by specifying --min and/or --max values manually.



pio provides just a command-line interface but there exists integrations for the following systems


pio is not really doing anything new and there are many similar projects including



License information is provided according to the REUSE specification. In summary:

  • pio source code is available under AGPL-3.0-or-later.
  • Other files are licensed under various Creative Commons licenses.

For more accurate information, check the individual files and .reuse/dep5.


Optimize images while maintaining the same perceived quality







No packages published