Difference between revisions of "Image Resizing"
(→Script for incron) |
(→SSI) |
||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | == SSI == | ||
+ | |||
+ | There is no way to test if a file exists with SSI (well apart from generating an error message, which can be customised) but we do have the original image size so we can test if width >= 640 and it's it's 2011/06 or later and then embed a scaled image, but it's not so simple when you have only '''string''' comparisons not ''numeric''' ones! | ||
+ | |||
+ | So we can have code like this to test if the image width is greater than 640 in SSI: | ||
+ | |||
+ | <syntaxhighlight lang="html5"> | ||
+ | <!--#set var="IMG_WIDTH" value="${image["img_width"]}"--> | ||
+ | <!--#set var="IMG_HEIGHT" value="${image["img_height"]}"--> | ||
+ | |||
+ | <noparse><!--#if expr="(${IMG_WIDTH} = /^....$/) || (${IMG_WIDTH} = /^.....$/) || (${IMG_WIDTH} = /^......$/)"--></noparse> | ||
+ | <comment>if we have more that 4 digits set SCALED=on</comment> <!--#set var="SCALED" value="on"--> | ||
+ | <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^7/) || (${IMG_WIDTH} = /^8/) || (${IMG_WIDTH} = /^9/)" --></noparse> | ||
+ | <comment>if we have 3 digits and the first one is greater than 6</comment> <!--#set var="SCALED" value="on"--> | ||
+ | <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^6/) && (${IMG_WIDTH} = /^.5/) || (${IMG_WIDTH} = /^.6/) || (${IMG_WIDTH} = /^.7/) || (${IMG_WIDTH} = /^.8/) || (${IMG_WIDTH} = /^.9/)" --></noparse> | ||
+ | <comment>if we have 3 digits and the first one is 6 and the second is greater or equal 5</comment> <!--#set var="SCALED" value="on"--> | ||
+ | <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^6/) && (${IMG_WIDTH} = /^.4/) && (${IMG_WIDTH} = /^..1/) || (${IMG_WIDTH} = /^..2/) || (${IMG_WIDTH} = /^..3/) || (${IMG_WIDTH} = /^..4/) || (${IMG_WIDTH} = /^..5/) || (${IMG_WIDTH} = /^..6/) || (${IMG_WIDTH} = /^..7/) || (${IMG_WIDTH} = /^..8/) || (${IMG_WIDTH} = /^..9/)" --></noparse> | ||
+ | <comment>if we have 3 digits and the first one is 6 and the second is 4 and the 3rd is greater than 0</comment> <!--#set var="SCALED" value="on"--> | ||
+ | <!--#else--> | ||
+ | <comment>we appear to have a number less or equal 640</comment> <!--#set var="SCALED" value="off"--> | ||
+ | <!--#endif--> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | And code like this to check the date is 2011/06 or later: | ||
+ | |||
+ | <syntaxhighlight lang="html5"> | ||
+ | <!--#set var="YEAR" value="${article.creationdate.formatted["yyyy"]}"--> | ||
+ | <!--#set var="MONTH" value="${article.creationdate.formatted["MM"]}"--> | ||
+ | <noparse><!--#if expr="${YEAR} != /^.0/"--></noparse> | ||
+ | <comment>if the year is greater than 2100</comment> <!--#set var="NEW_IMG" value="on"--> | ||
+ | <noparse><!--#elif expr="${YEAR} != /^..0/"--></noparse> | ||
+ | <comment>if the year is greater than or equal to 2010</comment> | ||
+ | <noparse><!--#if expr="${YEAR} != /^...0/"--></noparse> | ||
+ | <comment>if the year is greater than or equal to 2011</comment> | ||
+ | <noparse><!--#if expr="${YEAR} = 2011"--></noparse> | ||
+ | <comment>it's 2011</comment> | ||
+ | <noparse><!--#if expr="(${MONTH} != 01) && (${MONTH} != 02) && (${MONTH} != 03) && (${MONTH} != 04) && (${MONTH} != 05)"--></noparse> | ||
+ | <comment>it's 2011/06 or later</comment> <!--#set var="NEW_IMG" value="on"--> | ||
+ | <!--#else--> | ||
+ | <comment>it's 2011/05 or earlier</comment> <!--#set var="NEW_IMG" value="off"--> | ||
+ | <!--#endif--> | ||
+ | <!--#else--> | ||
+ | <comment>it's later than 2011</comment> <!--#set var="NEW_IMG" value="on"--> | ||
+ | <!--#endif--> | ||
+ | <!--#endif--> | ||
+ | <noparse><!--#elif expr="${YEAR} = /^200./"--></noparse> | ||
+ | <comment>if the year is less than 2010</comment> <!--#set var="NEW_IMG" value="off"--> | ||
+ | <!--#endif--> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | A lot of the above would probably be better off written in [http://fm-classic.sourceforge.net/ Free Marker Classic]... if we were running a version that supported numeric operators but it appears we are not... | ||
+ | |||
== Script for incron == | == Script for incron == | ||
− | incron can be set up to run on file creation, see: | + | incron can be set up to run on file creation but you have to '''be careful not to cause loops by creating new content in the same directory''', see: |
* http://inotify.aiken.cz/?section=incron&page=doc&lang=en | * http://inotify.aiken.cz/?section=incron&page=doc&lang=en | ||
* http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ | * http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/ | ||
− | + | Update the incron tab at the start of each month, run a script called /usr/local/bin/incron-update which contains: | |
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 15: | Line 67: | ||
DIR=/imc/mir/mayday/images/$YEAR/$MONTH | DIR=/imc/mir/mayday/images/$YEAR/$MONTH | ||
− | echo "$DIR IN_CLOSE_WRITE /usr/local/bin/exif-strip-resize \$@ | + | echo "$DIR IN_CLOSE_WRITE /usr/local/bin/exif-strip-resize \$@ \$#" > /etc/incron.d/mayday.conf |
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Via this crontab: | |
− | <syntaxhighlight lang=" | + | <syntaxhighlight lang="bash"> |
− | 0 0 1 * * /usr/local/bin/incron-update | + | 0 0 1 * * /usr/local/bin/incron-update ; /etc/init.d/incron restart |
</syntaxhighlight> | </syntaxhighlight> | ||
− | + | Save this script as /usr/local/bin/exif-strip-resize: | |
− | + | ||
− | / | + | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
<syntaxhighlight lang="bash"> | <syntaxhighlight lang="bash"> | ||
Line 36: | Line 82: | ||
# this script takes the full path to a jpeg file | # this script takes the full path to a jpeg file | ||
+ | # and the filename, paased from incrond | ||
# it scale big ones and also remove all exif metadata | # it scale big ones and also remove all exif metadata | ||
# from the jpeg | # from the jpeg | ||
− | # check for | + | # sub-directory for sacled images |
+ | SCALED=scaled | ||
+ | |||
+ | # check for the first command line argument | ||
if [[ $1 ]]; then | if [[ $1 ]]; then | ||
+ | # check it's a directory | ||
+ | if [[ -d $1 ]]; then | ||
+ | DIR=$1 | ||
+ | else | ||
+ | echo "$1 isn't a directory" | ||
+ | exit | ||
+ | fi | ||
+ | else | ||
+ | echo "You need to specify the path to a file as the first argument" | ||
+ | exit | ||
+ | fi | ||
− | + | # make a directory for the scaled images | |
+ | if [[ -d $DIR/$SCALED ]]; then | ||
+ | echo $DIR/$SCALED exists | ||
+ | else | ||
+ | mkdir $DIR/$SCALED | ||
+ | fi | ||
+ | if [[ $2 ]]; then | ||
+ | FILE=$2 | ||
+ | echo file is $DIR/$FILE | ||
# check the file exists | # check the file exists | ||
− | if [[ -f $FILE ]]; then | + | if [[ -f $DIR/$FILE ]]; then |
+ | # check if it's really a jpg | ||
+ | TYPE=$(file -bi $DIR/$FILE) | ||
+ | if [[ $TYPE = "image/jpeg; charset=binary" ]]; then | ||
− | + | # remove exif metadata preserving the image date | |
− | + | DATE=$(date -r $DIR/$FILE) | |
+ | exiv2 rm "$DIR/$FILE" | ||
− | # check | + | # check is a sub-directory for scaled images is writable |
− | + | if [[ -w $DIR/$SCALED ]]; then | |
− | if [[ $ | + | |
− | + | # generate scaled versions of images if they are greater than 640px wide | |
− | + | # or 1024px high, maintaining the aspect ratio | |
− | + | WIDTH=$(identify -format %w $DIR/$FILE) | |
− | + | if [[ $WIDTH -gt 640 ]]; then | |
− | + | convert "$DIR/$FILE" -resize 640x1024 -format jpeg -quality 80 "$DIR/$SCALED/$FILE" | |
− | + | touch -d "$DATE" "$DIR/$SCALED/$FILE" | |
− | + | fi | |
− | + | ||
− | + | ||
− | + | ||
− | + | # reset the file date | |
− | + | touch -d "$DATE" "$DIR/$SCALED/$FILE" | |
else | else | ||
− | + | echo $DIR/$SCALED is not writable | |
− | echo $ | + | |
− | + | ||
fi | fi | ||
− | |||
else | else | ||
− | + | echo "$DIR/$FILE is not a jpeg" | |
− | echo $ | + | |
− | + | ||
fi | fi | ||
− | |||
else | else | ||
− | + | echo "$DIR/$FILE does not exist" | |
− | echo $ | + | |
− | + | ||
fi | fi | ||
− | |||
else | else | ||
− | echo " | + | echo "$DIR/$FILE isn't a file" |
fi | fi | ||
Line 149: | Line 209: | ||
# or 1024px high, maintaining the aspect ratio | # or 1024px high, maintaining the aspect ratio | ||
WIDTH=$(identify -format %w $file) | WIDTH=$(identify -format %w $file) | ||
− | if [[ $WIDTH | + | if [[ $WIDTH -gt 640 ]]; then |
echo scalling $file | echo scalling $file | ||
convert "$file" -resize 640x1024 -format jpeg -quality 80 "$file.indyscaled.jpg" | convert "$file" -resize 640x1024 -format jpeg -quality 80 "$file.indyscaled.jpg" |
Latest revision as of 21:40, 28 June 2011
SSI
There is no way to test if a file exists with SSI (well apart from generating an error message, which can be customised) but we do have the original image size so we can test if width >= 640 and it's it's 2011/06 or later and then embed a scaled image, but it's not so simple when you have only string' comparisons not numeric ones!
So we can have code like this to test if the image width is greater than 640 in SSI:
<!--#set var="IMG_WIDTH" value="${image["img_width"]}"--> <!--#set var="IMG_HEIGHT" value="${image["img_height"]}"--> <noparse><!--#if expr="(${IMG_WIDTH} = /^....$/) || (${IMG_WIDTH} = /^.....$/) || (${IMG_WIDTH} = /^......$/)"--></noparse> <comment>if we have more that 4 digits set SCALED=on</comment> <!--#set var="SCALED" value="on"--> <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^7/) || (${IMG_WIDTH} = /^8/) || (${IMG_WIDTH} = /^9/)" --></noparse> <comment>if we have 3 digits and the first one is greater than 6</comment> <!--#set var="SCALED" value="on"--> <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^6/) && (${IMG_WIDTH} = /^.5/) || (${IMG_WIDTH} = /^.6/) || (${IMG_WIDTH} = /^.7/) || (${IMG_WIDTH} = /^.8/) || (${IMG_WIDTH} = /^.9/)" --></noparse> <comment>if we have 3 digits and the first one is 6 and the second is greater or equal 5</comment> <!--#set var="SCALED" value="on"--> <noparse><!--#elif expr="(${IMG_WIDTH} = /^...$/) && (${IMG_WIDTH} = /^6/) && (${IMG_WIDTH} = /^.4/) && (${IMG_WIDTH} = /^..1/) || (${IMG_WIDTH} = /^..2/) || (${IMG_WIDTH} = /^..3/) || (${IMG_WIDTH} = /^..4/) || (${IMG_WIDTH} = /^..5/) || (${IMG_WIDTH} = /^..6/) || (${IMG_WIDTH} = /^..7/) || (${IMG_WIDTH} = /^..8/) || (${IMG_WIDTH} = /^..9/)" --></noparse> <comment>if we have 3 digits and the first one is 6 and the second is 4 and the 3rd is greater than 0</comment> <!--#set var="SCALED" value="on"--> <!--#else--> <comment>we appear to have a number less or equal 640</comment> <!--#set var="SCALED" value="off"--> <!--#endif-->
And code like this to check the date is 2011/06 or later:
<!--#set var="YEAR" value="${article.creationdate.formatted["yyyy"]}"--> <!--#set var="MONTH" value="${article.creationdate.formatted["MM"]}"--> <noparse><!--#if expr="${YEAR} != /^.0/"--></noparse> <comment>if the year is greater than 2100</comment> <!--#set var="NEW_IMG" value="on"--> <noparse><!--#elif expr="${YEAR} != /^..0/"--></noparse> <comment>if the year is greater than or equal to 2010</comment> <noparse><!--#if expr="${YEAR} != /^...0/"--></noparse> <comment>if the year is greater than or equal to 2011</comment> <noparse><!--#if expr="${YEAR} = 2011"--></noparse> <comment>it's 2011</comment> <noparse><!--#if expr="(${MONTH} != 01) && (${MONTH} != 02) && (${MONTH} != 03) && (${MONTH} != 04) && (${MONTH} != 05)"--></noparse> <comment>it's 2011/06 or later</comment> <!--#set var="NEW_IMG" value="on"--> <!--#else--> <comment>it's 2011/05 or earlier</comment> <!--#set var="NEW_IMG" value="off"--> <!--#endif--> <!--#else--> <comment>it's later than 2011</comment> <!--#set var="NEW_IMG" value="on"--> <!--#endif--> <!--#endif--> <noparse><!--#elif expr="${YEAR} = /^200./"--></noparse> <comment>if the year is less than 2010</comment> <!--#set var="NEW_IMG" value="off"--> <!--#endif-->
A lot of the above would probably be better off written in Free Marker Classic... if we were running a version that supported numeric operators but it appears we are not...
Script for incron
incron can be set up to run on file creation but you have to be careful not to cause loops by creating new content in the same directory, see:
- http://inotify.aiken.cz/?section=incron&page=doc&lang=en
- http://www.cyberciti.biz/faq/linux-inotify-examples-to-replicate-directories/
Update the incron tab at the start of each month, run a script called /usr/local/bin/incron-update which contains:
#!/bin/bash YEAR=$(date +%Y) MONTH=$(date +%m) DIR=/imc/mir/mayday/images/$YEAR/$MONTH echo "$DIR IN_CLOSE_WRITE /usr/local/bin/exif-strip-resize \$@ \$#" > /etc/incron.d/mayday.conf
Via this crontab:
0 0 1 * * /usr/local/bin/incron-update ; /etc/init.d/incron restart
Save this script as /usr/local/bin/exif-strip-resize:
#!/bin/bash # this script takes the full path to a jpeg file # and the filename, paased from incrond # it scale big ones and also remove all exif metadata # from the jpeg # sub-directory for sacled images SCALED=scaled # check for the first command line argument if [[ $1 ]]; then # check it's a directory if [[ -d $1 ]]; then DIR=$1 else echo "$1 isn't a directory" exit fi else echo "You need to specify the path to a file as the first argument" exit fi # make a directory for the scaled images if [[ -d $DIR/$SCALED ]]; then echo $DIR/$SCALED exists else mkdir $DIR/$SCALED fi if [[ $2 ]]; then FILE=$2 echo file is $DIR/$FILE # check the file exists if [[ -f $DIR/$FILE ]]; then # check if it's really a jpg TYPE=$(file -bi $DIR/$FILE) if [[ $TYPE = "image/jpeg; charset=binary" ]]; then # remove exif metadata preserving the image date DATE=$(date -r $DIR/$FILE) exiv2 rm "$DIR/$FILE" # check is a sub-directory for scaled images is writable if [[ -w $DIR/$SCALED ]]; then # generate scaled versions of images if they are greater than 640px wide # or 1024px high, maintaining the aspect ratio WIDTH=$(identify -format %w $DIR/$FILE) if [[ $WIDTH -gt 640 ]]; then convert "$DIR/$FILE" -resize 640x1024 -format jpeg -quality 80 "$DIR/$SCALED/$FILE" touch -d "$DATE" "$DIR/$SCALED/$FILE" fi # reset the file date touch -d "$DATE" "$DIR/$SCALED/$FILE" else echo $DIR/$SCALED is not writable fi else echo "$DIR/$FILE is not a jpeg" fi else echo "$DIR/$FILE does not exist" fi else echo "$DIR/$FILE isn't a file" fi
Script to run via cron
This is a script to be run via cron, perhaps once a min to remove exif metadata and to scale jpeg images if they need it.
#!/bin/bash # this script takes a directory with some jpeg files in and # will scale the big ones and also remove all exif metadata # from the jpegs # you can set an optional AGE vairable here, if it's set then only # files that are newer than AGE will be looked at -- this is handy # if the script is running on a cron job, set it to a tile just longer # than the cron interval, use mins for the value AGE=200 # Directory of images is passed to this script via $1, if it's # not then we assume that we should run in the current directory. if [[ $1 ]]; then # change to the directory where the images are cd $1 DIR=$(pwd) else DIR=$(pwd) fi # get a list of the files, omitting ones that have already been scaled if [[ $AGE ]]; then FILES=$(find -P $DIR -type f -cmin -$AGE -name '*.jpg' ! -name '*\.indyscaled\.jpg') else FILES=$(find -P $DIR -type f -name '*.jpg' ! -name '*\.indyscaled\.jpg') fi for file in $FILES; do #echo file: $file # check the file exists if [[ -f $file ]]; then # check if we can write to the file if [[ -w $file ]]; then # check if it's really a jpg TYPE=$(file -bi $file) if [[ $TYPE = "image/jpeg; charset=binary" ]]; then # remove exif metadata preserving the image date DATE=$(date -r $file) exiv2 rm "$file" # generate scaled versions of images if they are greater than 640px wide # or 1024px high, maintaining the aspect ratio WIDTH=$(identify -format %w $file) if [[ $WIDTH -gt 640 ]]; then echo scalling $file convert "$file" -resize 640x1024 -format jpeg -quality 80 "$file.indyscaled.jpg" touch -d "$DATE" "$file.indyscaled.jpg" fi # reset the file date touch -d "$DATE" "$file" else echo $file is not a jpeg fi else echo $file is not writable fi else echo $file does not exist fi done