Drop #497 (2024-07-10): Picture Perfect

trimage; rimage; imaginary

In light of the recent Ghostscript vulnerability, which can be exposed if you use ImageMagick in image processing pipelines, I thought it might be useful to cover some different image processing tools/self-hostable microservices. So, that’s the focus of today’s Drop.


TL;DR

(This is an AI-generated summary of today’s Drop using Sonnet via Perplexity.)

  • trimage (https://trimage.org/): A cross-platform GUI and CLI tool for lossless image compression of PNG and JPG files, utilizing optipng, pngcrush, advpng, and jpegoptim for optimal compression while maintaining quality.
  • rimage (https://github.com/SalOne22/rimage): A Rust-based CLI tool supporting modern image formats (JPEG, JPEG XL, PNG, AVIF, WebP), offering parallel processing, fine-grained quality control, and advanced features like quantization and dithering.
  • imaginary (https://github.com/h2non/imaginary): A fast, Go-based HTTP microservice for image processing, offering resizing, cropping, and transformation capabilities through a REST API, with support for remote image fetching and robust access controls.

trimage

Photo by Nikolaos Dimou on Pexels.com

Trimage (GH(“trim the image”) is a neat, versatile image optimization tool that efficiently compresses image files without sacrificing quality. It’s a cross-platform application that combines the power of several command-line utilities into a very friendly graphical interface and CLI, streamlining the process of reducing file sizes for both PNG and JPG formats.

The tool leans heavily on the capabilities of optipngpngcrushadvpng, and jpegoptim to ensure we get optimal compression, depending on what file type we send to the tool. A notable feature and focus of trimage is that it aims to achieve lossless compression at the highest available levels. It does a pretty solid job at doing so, and generally produces the smallest, lossless files.

The GUI version sports a traditional file dialog, but also supports drag-and-drop (I’ll never get used to that in any tool). The CLI version works great in pipelines, or for one-off conversion tasks in the terminal.

In addition to compressing image files, the application can automagically strip away EXIF and other metadata. The further reduces file sizes without impacting visual quality.

It’s been around for a ~decade, has a cool community, and is a good choice for predictable output.

rimage

Photo by Karolina Kaboompics on Pexels.com

If an “all-in-one-binary” solution is more to your liking, you may be up for kicking the tyres on rimage (GH), a Rust-based CLI tool that’s been around for just over a year.

It supports a wide array of modern image formats, including JPEG, JPEG XL, PNG, AVIF, and WebP. It also leverages parallel processing and can optimizate multiple images at the same time.

With it, we have fine-grained control over image quality (including lossless options, like trimage). Folks with more advanced needs will like the tool’s support for quantization and dithering, two techniques that can dramatically reduce file sizes while maintaining acceptable image quality. rimage also has options for resizing images.

The README and Rust docs site are well-crafted, so I’ll leave you to explore them vs. suffer through more blathering.

imaginary

Photo by Reagan Ross on Pexels.com

If a web-service/app is more aligned with your image processing needs, you should def take a look at imaginary (it also has CLI functionality, dpending on the docker run incantation). It’s written in Go (using bimg/libvips image processing libraries), and offers blazing-fast image manipulation through a straightforward API. It can resize, crop, rotate, and transform images at speeds up to 10x faster than traditional tools like ImageMagick.

The REST API also lets us chain together complex sequences of image operations in a single HTTP request; and this self-described microservice also has built-in support for fetching images from remote URLs, making it easy to integrate into existing workflows.

Security-conscious humans will appreciate imaginary’s robust access controls. The service can be configured to restrict image processing to specific origins, preventing abuse from malicious actors (but, please consider using Tailscale, and avoid putting any service on the internet if at all possible). An optional URL signature system adds an extra layer of protection for sensitive assets.

In benchmark tests, a single imaginary instance processed over 20 concurrent image resize operations per second on modest hardware. The Go runtime’s efficient concurrency model, combined with libvips‘ low memory footprint means imaginary can scale super-well.

This project, too, has an excellent README and associated documentation, so you should also def check those out.

FWIW, it worked very well under Orbstack (the excellent Docker replacement for macOS), with baseline memory usage at around ~50 MiB.

FIN

Remember, you can follow and interact with the full text of The Daily Drop’s free posts on Mastodon via @dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev ☮️

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.