Almost all image quality losses occur the first time an image is compressed as JPEG. Regardless of how many times a JPEG is recompressed with the same settings, generational losses are limited to rounding error.
MCU boundaries remain are intact (8x8 blocks).
Chroma subsampling is disabled.
Constant DQT (same quality setting).
However, rounding errors may be large for each iteration that the above criteria are not met, and it is prudent to keep backups of all original files.
Convert colorspace. If desired, downsample color information (chroma subsampling) (Lossy). If not downsampled, loss of information is the result of rounding error.
Segmentation. Divide each channel into 8x8 blocks (MCU = Minimal Coding Unit). (Lossless)
Note: If chroma subsampling is enabled, MCUs may effectively be 16x8, 8x16, or 16x16, in terms of the original image. However, the MCUs are still all 8x8 blocks.
Discrete Cosine Transform (DCT) on each MCU. Loss of information is the result of rounding error.
Quantization. The value in each cell of the MCU is divided by a number specified in a quantization table (DQT). Values are rounded down, many of which will become zero. This is the primary lossy portion of the algorithm.
Zig-Zag Scan. Rearrange values in each MCU into a sequence of numbers following a zig-zag pattern. The zeros that occurred during quantization will be grouped together. (Lossless)
DPCM = Differential Pulse Code Modulation. Convert the number sequences into a form that is easier to compress. (Lossless)
RLE = Run Length Encoding. Consecutive zeros are compressed. (Lossless)
Entropy/Huffman Coding. (Lossless)
Recompressing JPEGs
Note that downsampling the color channels and quantization are the only intentionally lossy steps. Setting aside rounding error for now, all other steps are lossless. Once quantization has occurred, reversing and repeating the step gives identical results. In other words, re-quantization (with the same DQT) is lossless.
In principle, it is possible to create a resampling algorithm that is lossless after the first pass. However, with the implementation in ImageMagick, colors may shift drastically before steady state is reached, as seen in ths' image.
Given optimal conditions, recompressing a JPEG with the same quality settings would result in the exact same JPEG. In other words, recompressing JPEGs is potentially lossless. In practice, recompressing JPEGs is not lossless, but subject to, and limited by, rounding error. Although rounding errors often eventually converge to zero, so that the exact same image is re-created, chroma subsampling may result in significant color changes.
Demonstration (same quality setting)
I wrote the following bash
script, which uses ImageMagick to repeatedly recompress a JPEG file at a given quality setting:
#!/usr/bin/env bash
n=10001; q1=90
convert original.png -sampling-factor 4:4:4 -quality ${q1} ${n}.jpg
while true ; do
q2=${q1} # for variants, such as adding randomness
convert ${n}.jpg -quality ${q2} $((n+1)).jpg
#\rm $((n-5)).jpg # uncomment to avoid running out of space
n=$((n+1))
echo -n "$q2 "
md5sum ${n}.jpg
done
After letting it run for a few hundred iterations, I ran md5sum
on the results:
d9c0d55ee5c8b5408f7e50f8ebc1010e original.jpg
880db8f146db87d293def674c6845007 10316.jpg
880db8f146db87d293def674c6845007 10317.jpg
880db8f146db87d293def674c6845007 10318.jpg
880db8f146db87d293def674c6845007 10319.jpg
880db8f146db87d293def674c6845007 10320.jpg
We can see that, indeed, the rounding error has converged to zero, and the exact same image is being reproduced, over and over.
I have repeated this multiple times with different images and quality settings. Usually, steady state is reached, and the exact same image is reproduced over and over.
I have attempted to replicate mattdm's results using Imagemagick on Ubuntu 18.04. The original was a raw conversion to TIFF in Rawtherapee, but it seems to be no longer available. In its place, I took the enlarged version and reduced it to its original size (256x256). Then I repeatedly recompressed at 75 until I got convergence. Here is the result (original, 1, n, difference):
My results are different. Without the true original, the reason for the difference is impossible to determine.
I recompressed the image from the upper left corner of the montage until convergence at 90. This is the result (original, 1, n, difference):
After enabling chroma subsampling, the colors do change by the time steady state is reached.
Changing among a small number of settings
By modifying the variable q2
, the quality setting can be limited to a set of evenly distributed values.
q2=$(( (RANDOM % 3)*5 + 70 ))
For a small number of setting choices, equilibrium may eventually reached, which is seen when md5 values begin recurring. It seems the larger the set, the longer it takes, and the worse the image becomes, before equilibrium can be reached.
What seems to happen at equilibrium is the DCT coefficient prior to quantization has to be divisible all (or most) of the quantum values. For example, if switching between two DQTs where DCT coefficient is divided alternately by 3 and 5, equilibrium will be reached when the DCT coefficient is divisible by 15. This explains why the drop in quality is much greater than the difference between the original settings.
Changing among a larger number of settings
Eeyore is not happy when q2
is changed like so:
q2=$(( (RANDOM % 9) + 90 ))
To make a video, use ffmpeg
:
rename 's@1@@' 1*.jpg
ffmpeg -r 30 -i %04d.jpg -c:v libx264 -crf 1 -vf fps=25 -pix_fmt yuv420p output.mp4
Watching the first 9999 iterations is almost like watching water boil. Might want to double playback speed. Here is Eeyore after 11999 iterations:
What if MCU boundaries change?
If changes occur a limited number of times, repeatedly recompressing is likely to reach steady state. If changes occur at each iteration, the image will probably degrade in a manner similar to when DQT changes.
- This is what happens in videos that rotate an image with dimensions that are not divisible by 8.
What about editing?
The effect of recompressing after editing depends on the particular edit performed. For instance, saving at the same quality setting after reducing JPEG artifacts would reintroduce the same artifacts. However, applying a localized change, such as a healing brush, would not affect areas that were not touched.
The greatest drop in image quality occurs the first time the file is compressed at a given quality setting. Subsequently recompressing with the same setting should not introduce any change greater than rounding error. So I would expect edit-resave cycles at a given quality setting to look like any other image saved with the same quality setting (as long as MCU boundaries stay intact and chroma subsampling is disabled).
What about those videos?
Can I over-write my originals with recompressed JPEGs?
It is prudent to keep backups of all original files, but if you accidentally overwrite one, the damage is likely limited. It would also be fine to work in JPEG with chroma subsampling disabled.
JPEG cannot be used for images that use more than 8 bits per color.