It details a company that has come up with a way to optimize an image so that it visually looks virtually identical to the original, but takes up a fraction of the original file size. That's awesome! I even tested it against some image files:
|Black Sea Nettles - JPEG shrunk using custom algorithm.|
- 24 megapixel JPEG / 12MB in size => 1.6MB resulting file after JPEGmini.
- 12 megapixel JPEG / 4.8MB in size => 1.1MB resulting file after JPEGmini.
I performed a difference test against the original and the JPEGmini version. They are virtually identical. If you take the resulting difference image and adjust the levels, there are in fact different, but the difference can be attributed to minor random noise vs compression artifacts. Amazing!
DIY JPEG Compression Improvement
Being the kind of guy I am, I was wondering... how did they do this? According to the JPEGmini site:
- improved algorithms
- compressing to a level just before artifacting becomes an issue
Well, thinking that I could at least get some improvement, I leverage ImageMagick and some shell scripting.
I tested with the same images and came up with the following:
- 24MP / 12MB => 2.8MB (1.7MB with updates below) (jpeg compression quality @73%)
- 12MP / 4.6MB => 1.1MB (jpeg compression quality @87%)
The images produced were likewise virtually the same and a difference mask between the two in photoshop shows nothing, unless you auto-level. The amount of difference between my reduced images and JPEGmini's reduced images were comparable. No new JPEG compression algorithm on my part, just applying basic JPEG compression guidelines from FileFormat's JPEG Page:
The JPEG library supplied by the Independent JPEG Group uses a quality setting scale of 1 to 100. To find the optimal compression for an image using the JPEG library, follow these steps:
- Encode the image using a quality setting of 75 (-Q 75). If you observe unacceptable defects in the image, increase the value, and re-encode the image. If the image quality is acceptable, decrease the setting until the image quality is barely acceptable. This will be the optimal quality setting for this image. Repeat this process for every image you have (or just encode them all using a quality setting of 75).
The process that my script goes through:
- Compress original image at 99% image quality
- Do a comparison metric between the original and the new image.
- If the compression has resulted in a difference greater than a certain threshold, use the compression quality percentage prior to the current one.
- If difference is less than threshold, decrease image quality by 1% and repeat from step #2.
Using this process against the whole image, I could reduce <12MP files down to ranges similar to what JPEGmini was able to achieve, albeit slower. For files >12MP, I would achieve great savings in space, but not as great as JPEGmini, for a given threshold of difference.
Edit: Upon reviewing my notes, it looks like the threshold for <12MP and for >12MP is different from the JPEGmini files. When optimizing with the expanded threshold for larger files, I am able to get comparable to what JPEGmini gets.
How I Did The Compression Process
- Use ImageMagick's "compare" to generate "image distortion" readings:
- convert -quality PERCENTAGE% original-image.jpg compressed-image.jpg
- compare -verbose -metric mae original-image.jpg compressed-image.jpg
- Using the example file from JPEGmini, establish a baseline:
- 24MP image = ceiling of 370 points of distortion
- 12MP image = ceiling of 265 points of distortion
- Starting at 99% quality for JPEG compression, continue to reduce quality until the distortion measured exceeds the baseline. If it does, use the compression level from before.
The level of acceptable compression will differ from image to image. If the image has more pixels/images, then it will be able to contain more points of distortion before the image quality suffers.
To optimize the speed, especially for larger images, I scaled down the original image and performed the tests on the scaled down images. Once the ideal was located, I performed the compression on the original with the quality determined from the scaled down image. For very large images, I take a crop from center of the image, which results in a more accurate quality prediction.
I can see why most applications don't both with this process... it's basically exhaustive testing to determine how much you can compress before image quality is degraded unacceptably. In addition to scaling down the image, I could also do quality percentage point skipping and backtracking when quality is degraded.
What would be ideal is an API and library set that does an image quality analysis and gives you an optimally compressed JPEG out of the box. That is the value add of what JPEGmini is offering, and I think that it is a technology which any company involved with image storage should look into.
Note, the shell script/etc are not published, as the goal was to explore whether or not it could be done. Based on the description above, one can easily write the appropriate wrapper script or use the appropriate java/python/php/etc hooks.
- Improved optimization to the quality locating logic resulted in a reduction from 5 minutes to 13 seconds to locate the quality setting and compress a 24MP image.
- Planning on creating a Lightroom 3 export plugin for this scripted method.
- Planning on trying to reduce the time required from 13 seconds down to under 10 seconds.