Flaca is a CLI tool for x86-64 Linux machines that simplifies the task of maximally, losslessly compressing GIF, JPEG, and PNG images for use in production web environments.
It prioritizes compression over speed or resource modesty, and runs best on systems with multiple CPUs. There are only so many ways to be a GIF or JPEG, but calculating the optimal construction for a PNG can take a lot of work!
Compression is mainly achieved through the removal of metadata and optimization of pixel tables. Under the hood, flaca leverages Gifsicle for GIFs, the jpegtran
functionality from MozJPEG for JPEG images, and a combination of Oxipng and Zopflipng for PNG images.
For web images, metadata is just so much wasted bandwidth. Stock photos in particular can be bloated 50% or more with embedded keywords and descriptions that browsers make zero use of. Removing that data — particularly at scale — leads to both lower hosting costs for site operators and faster page loads for visitors.
And it helps close the digital divide.
But in other contexts, metadata may matter.
As a general rule, you should not try to feed your entire personal media library or raw print/design assets to flaca or it may eat something important.
Debian and Ubuntu users can just grab the pre-built .deb
package from the latest release.
This application is written in Rust and can alternatively be built/installed from source using Cargo:
# See "cargo install --help" for more options.
cargo install \
--git https://github.com/Blobfolio/flaca.git \
--bin flaca
Note that when building from source, you'll need to have make
, nasm
, and the development headers for libjpeg
and libpng
installed beforehand or Cargo will pop an error. (If that happens, just install the missing thing and try again.)
It's easy. Just run flaca [FLAGS] [OPTIONS] <PATH(S)>…
.
The following flags and options are available:
Short | Long | Value | Description |
---|---|---|---|
-h |
--help |
Print help information and exit. | |
-j |
<NUM> |
Limit[^1] parallelization to this many threads (instead of using all logical cores). | |
-l |
--list |
<FILE> |
Read (absolute) image and/or directory paths from this text file — or STDIN if "-" — one entry per line, instead of or in addition to the trailing <PATH(S)> . |
--max-resolution |
<NUM> |
Skip images containing more than <NUM> total pixels. |
|
--no-gif |
Skip GIF images. | ||
--no-jpeg |
Skip JPEG images. | ||
--no-png |
Skip PNG Images. | ||
--no-symlinks |
Ignore symlinks (rather than following them). | ||
--preserve-times |
Preserve file access/modification times. | ||
-p |
--progress |
Show pretty progress while minifying. | |
-z |
--zopfli-iterations |
<NUM> |
Override the number of zopfli iterations when compressing PNGs. |
-V |
--version |
Print version information and exit. |
You can feed it any number of file or directory paths in one go, and/or toss it a text file using the -l
option. Directories are searched recursively.
To reduce pointless I/O, flaca will silently ignore file paths lacking an appropriate extension, i.e. .gif
, .jp(e)g
, or .png
(case-insensitive).
Flaca can cross filesystem and user boundaries, provided the user running the program has the relevant read/write access. (Not that you should run it as root
, but if you did, images should still be owned by www-data
or whatever after re-compression.)
Some quick examples:
# Compress one file.
flaca /path/to/image.jpg
# Tackle a whole folder at once with a nice progress bar:
flaca -p /path/to/assets
# Tackle a whole folder, but only look for JPEG images.
flaca --no-png /path/to/assets
# Or load it up with a lot of places separately:
flaca /path/to/assets /path/to/favicon.png …
# Limit parallel processing to two images at a time.
flaca -j2 /path/to/assets
# Zopfli compression is slow and scales more or less linearly with the number
# of iterations set. Flaca uses the same default as zopflipng: 60 for small
# images, 20 for larger ones. If you're willing to trade longer processing
# times for extra (potential) byte savings, you can try scaling up the
# iteration count:
flaca -z 500 /path/to/favicon.png
# Or, conversely, if you want to speed up PNG compression at the expense of a
# few extra bytes, try dialing the count back:
flaca /path/to/huge.png -z 1
[^1] GIF images require a single, dedicated thread for optimization, separate from the -j
limit applied to all other work. Unless/until a GIF turns up, it will just sit idle, so shouldn't noticeably impact most workloads.