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.
The JPEG standard has a number of file compliancy variations which were created for specific reasons, two types which are often used are EXIF and JFIF.
Although both files are classed as JPEG files and appear on a computer with the JPEG extension the difference is due to the supplementary data which is added to the original image during processing in camera or in computer. This data is usually stored in an areas that are called "APPn" (where "n" is the number 0,1,2 etc).
Most imaging software applications can open both types of JPEG file, but most digital cameras can only display EXIF format images. When a EXIF file is opened in an imaging program like Photoshop and then saved, the file is changed into a JFIF format with a result that the image can no longer be opened by the camera and the shooting data is lost.
EXIF
The EXIF format was created for use in digital cameras, the APPn stores information such as the state of the camera when the image was recorded (shutter, aperture white balance etc).
JFIF
The JFIF variation is commonly used in the imaging industry, most software applications save files in this format. JFIF uses the APPn to store information such as copyright and captions (IPTC text) and profile information for colour management (icm data).
You can try ExifTool and run this command, but it is possible that your camera will be unable to display the images, as the shooting data is lost.
exiftool "-exif:all<jfif:all" "-thumbnailimage<jfif:thumbnailimage" FILE
Best Answer
If you use imagemagick? and say
Tell me if it works right for you