Batch-convert files to JXL

JPG and PNG are old. JPEG-XL is the hype new image format. It has many cool features which I won't exhaustively list here. https://jpeg.org/jpegxl/

If you decide to convert your files, you will find cjxl can be slow on the slow presets. Also, compressing an image with multiple threads reduces compression ratio.

So, it is typically better to compress each image with 1 thread, which gets better compression as no data needs to be shared, and just compress more images at the same time. Ie: instead of compressing 1 image with 8 threads, compress 8 images with 1 thread each.

Note, this means you are going to use massive amounts of RAM with slow presets. You have been warned.

First, get the list of images you want to compress. A simple way is

find -name "*.JPG" | tee /tmp/files

cjxl can work with either jpg or png as input (use imagemagick if you need more).

Next, I use GNU Parallel to batch process these:

parallel --ungroup -j16 -v -q -a /tmp/files cjxl -e 9 --num_threads=0 --lossless_jpeg=1 -d 0 "{}" "{.}.jxl"

While CJXL preserves some metedata, it is not the complete bundle if you use something like digikam to manage photos.

You can use exiftool (or probably exiv2) to re-write the metadata either from the image or XMP files.

parallel --ungroup -j24 -v -q -a /tmp/files exiftool -overwrite_original -TagsFromFile "{}.xmp" "{.}.jxl.xmp"

CAUTION! At the time of writing, exiftool can NOT write to JXL files - it will, but it can only be read by exiftool. Use XMP files or another mechanism for the time being!