Yes, there will be loss of quality, even at 100%. That said, is it likely to be all but unnoticeable immediately. If you have Photoshop you can easily confirm the loss of quality:
- Load up the original and the resaved image as two layers in the same image.
- Change the top one's display mode to Difference.
- Select All and then Copy Merged (Ctrl+A and Ctrl+Shift+C by default).
- Paste the result in as a new layer.
- Using the Magic Wand tool, (Tolerance 0, Contiguous unchecked, Antialias unchecked), select an all-black pixel (RGB 0, 0, 0).
If all pixels are selected (which won't happen), the two images are identical. Otherwise the unselected areas have been modified.
If you resave the same JPEG a few times it will become much more noticeable.
Edit: Fixed some issues with the original script. Added an alternative one based on Marcks Thomas' proposition.
Edit 2: Updated cutoff values based on a number of test runs. I am still not sure how to estimate file sizes for greyscale images. If you are working with a large number of images outside of RGB colour schemes you might want to implement the first script as a fallback mode to the second one.
Edit 3: Added optipng
integration. This optimizes PNG file sizes without any quality loss. See here for more information. Some smaller improvements.
Version 0.1
Important note: This script is deprecated. Newer versions are far more efficient.
Alright, my question might have been slightly too localized, so I put some time into it and compiled the script myself:
#!/bin/bash
# AUTHOR: (c) MHC (http://askubuntu.com/users/81372/mhc)
# NAME: Intelliconvert 0.1
# DESCRIPTION: A script to automate and optimize the choice between different image formats.
# LICENSE: GNU GPL v3 (http://www.gnu.org/licenses/gpl.html)
# REQUIREMENTS: Imagemagick
ORIGINAL="$1"
###Filetype check###
MIME=$(file -ib "$ORIGINAL")
if [ "$MIME" = "image/png; charset=binary" ]
then
echo "PNG Mode"
###Variables###
##Original Image##
FILENAME=$(basename "$ORIGINAL")
PARENTDIR=$(dirname "$ORIGINAL")
SUBFOLDER=$(echo "$PARENTDIR" | cut -d"/" -f10-)
ORIGARCHIVE="~/ORIG"
##Converted Image##
TEMPDIR="/tmp/imgcomp"
CONVERTED="$TEMPDIR/$FILENAME.jpg"
##Image comparison##
DIFFLO="50"
DIFFHI="75"
CUTOFF="1000000"
##DEBUG
echo "#### SETTINGS ####"
echo "Filepath to original = $ORIGINAL"
echo "Filename= $FILENAME"
echo "Parent directory = $PARENTDIR"
echo "Archive directory = $ORIGARCHIVE"
echo "Temporary directory = $TEMPDIR"
echo "Filepath to converted image = $CONVERTED"
echo "Low cut-off = $DIFFLO"
echo "High cut-off = $DIFFHI"
###Conversion###
convert -quality 92 -flatten -background white "$ORIGINAL" "$CONVERTED"
###Comparison###
F1=$(stat -c%s "$ORIGINAL" )
F2=$(stat -c%s "$CONVERTED" )
FQ=$(echo "($F2*100/$F1)" | bc)
#Depending on filesize we use a different Cut-off#
if [ "$F1" -ge "$CUTOFF" ]
then
DIFF="$DIFFHI"
else
DIFF="$DIFFLO"
fi
##DEBUG
echo "### COMPARISON ###"
echo "Filesize original = $F1 Bytes"
echo "Filesize converted = $F2 Bytes"
echo "Chosen cut-off = $DIFF %"
echo "Actual Ratio = $FQ %"
if [ "$FQ" -le "$DIFF" ]
then
echo "JPEG is more efficient, converting..."
mv -v "$CONVERTED" "$PARENTDIR"
mkdir -p "$ORIGARCHIVE/$SUBFOLDER"
mv -v "$ORIGINAL" "$ORIGARCHIVE/$SUBFOLDER"
else
echo "PNG is fine, exiting."
rm -v "$CONVERTED"
fi
else
echo "File does not exist or unknown MIME type, exiting."
fi
The script works great in combination with Watcher.
This is my first proper script, so there might be some unresolved bugs and issues I just didn't see. Feel free to use it for yourself and improve it. If you do so, I'd appreciate it if you could leave a comment here, so that I can learn from it.
Version 0.2.1
A more efficient way of finding the right format can be achieved by comparing the original's file size to its estimated size as an uncompressed image:
#!/bin/bash
# AUTHOR: (c) MHC (http://askubuntu.com/users/81372/mhc)
# NAME: Intelliconvert 0.2.1
# DESCRIPTION: A script to automate and optimize the choice between different image formats.
# LICENSE: GNU GPL v3 (http://www.gnu.org/licenses/gpl.html)
# REQUIREMENTS: Imagemagick, Optipng
################ Filetype Check#################
MIME=$(file -ib "$1")
if [ "$MIME" = "image/png; charset=binary" ]
then
echo "###PNG Mode###"
####################Settings####################
##Folders##
ORIGARCHIVE="~/ORIG"
##Comparison##
DIFFLO="25"
DIFFHI="20"
CUTOFF="1000000"
################################################
###Variables###
ORIGINAL="$1"
FILENAME=$(basename "$ORIGINAL")
PARENTDIR=$(dirname "$ORIGINAL")
SUBFOLDER=$(echo "$PARENTDIR" | cut -d"/" -f10-)
CONVERTED="$PARENTDIR/$FILENAME.jpg"
#DEBUG#
echo "###SETTINGS###"
echo "Filepath to original = $ORIGINAL"
echo "Filename= $FILENAME"
echo "Parent directory = $PARENTDIR"
echo "Archive directory = $ORIGARCHIVE"
echo "Filepath to converted image = $CONVERTED"
echo "Low cut-off = $DIFFLO"
echo "High cut-off = $DIFFHI"
###Image data###
WIDTH=$(identify -format "%w" "$ORIGINAL")
HEIGHT=$(identify -format "%h" "$ORIGINAL")
ZBIT=$(identify -format "%z" "$ORIGINAL")
COL=$(identify -format "%[colorspace]" "$ORIGINAL")
F1=$(stat -c%s "$ORIGINAL")
if [ "$COL" = "RGB" ]
then
CHANN="3"
else
CHANN="1"
fi
###Cutoff setting###
if [ "$F1" -ge "$CUTOFF" ]
then
DIFF="$DIFFHI"
else
DIFF="$DIFFLO"
fi
###Calculations on uncompressed image###
BMPSIZE=$(echo "($WIDTH*$HEIGHT*$ZBIT*$CHANN/8)" | bc)
FR=$(echo "($F1*100/$BMPSIZE)" | bc)
#DEBUG#
echo "###IMAGE DATA###"
echo "Image Dimensions = $WIDTH x $HEIGHT"
echo "Colour Depth = $ZBIT"
echo "Colour Profile = $COL"
echo "Channels = $CHANN"
echo "Estimated uncompressed size = $BMPSIZE"
echo "Actual file size = $F1"
echo "Estimated size ratio = $FR %"
echo "Cutoff at $DIFF %"
###Backup###
echo "###BACKUP###"
mkdir -p "$ORIGARCHIVE/$SUBFOLDER" #keep the original folder structure
cp -v "$ORIGINAL" "$ORIGARCHIVE/$SUBFOLDER"
echo ""
###Comparison###
if [ "$FR" -ge "$DIFF" ]
then
echo "JPEG is more efficient, converting..."
convert -quality 92 -flatten -background white "$ORIGINAL" "$CONVERTED"
echo "Done."
echo "Cleaning up..."
rm -v "$ORIGINAL"
else
echo "PNG is fine, passing over to optipng."
echo "Optimizing..."
optipng "$ORIGINAL"
echo "Done."
fi
################ Filetype Check#################
else
echo "File does not exist or unknown MIME type, exiting."
fi
Props to @Marcks Thomas for the great idea.
Best Answer
There are a couple of nice posts here that seem to describe why Progressive compression may be better and it seems to come down to the fact that in Progressive JPEG the compressed data is ordered more efficiently and that blocky image data and noise get separated and compressed separately.
I've highlighted the important pieces below, they describe it better than I ever could.
As a result I would expect that progressive JPEG is better compression, but not any significant change in image quality.