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.
With the help of a ffmpeg contributor it was found out that both ffmpeg and libav create flawless lossless Quicktime files. The problem seems to be the graphic card driver displaying the videos wrongly (since GStream based players and VLC both display it wrongly, however VLC is exporting perfect PNGs of video frames). If you want to check if a video is really containing the frames pixel by pixel, try using
$ ffmpeg -i input.png -vcodec qtrle out.mov
$ ffmpeg -i input.png -f framecrc -
$ ffmpeg -i out.mov -f framecrc -
This will output frame data checksums.
For a visual comparison, convert the lossless video back to single frames and compare those.
Best Answer
As you haven't given the command line you used we can only guess, but this ffmpeg command will generate a lossless video clip from files named
frame00.png
,frame01.png
,frame02.png
, etc.The resulting video should work as input to at least
ffmpeg
,mplayer
and VLC.Adjust the framerate using an
-r
option before the-i
.