#!/bin/sh # # Description - read photos from CF/SD memory card, copy them to destination folder, # auto-rotate images (Exif info used), add date-time to filename (Exif info used) # # Usage: # foto-copy -- just copy all photos from memory card to your disk # foto-copy remove -- copy all photos to your disk and remove them from your memory card # # Requirements: # jhead - renaming # exiv2 - Exif tag manipulations # dcraw (for RAW photos) # ppmtojpeg (for RAW photos) # jpegtran - lossless JPEG rotation # acpi - only for laptops # # Developed by Lubomir Host 'rajo' # Copyright (c) 2005-2009 Platon Group, http://platon.sk/ # Licensed under terms of GNU General Public License. # All rights reserved. # # Changelog: # 2005-??-?? - created # 2006-08-14 - enhanced - images are auto-rotated - Exif tag Exif.Image.Orientation is used # # $Platon: scripts/shell/photo-managment/foto-copy,v 1.5 2011-03-01 22:31:31 rajo Exp $ # where to mount you memory card - configure in /etc/fstab something like this: # /dev/sdb1 /foto vfat iocharset=iso8859-2,umask=002,codepage=852,showexec,users,gid=users,noauto,nodev,nosuid,quiet 0 0 MOUNTPOINT="/foto" # where to copy your photos for sorting - /home/rajo/media/foto/2006/ DEST="$HOME/media/foto/`date +%Y`" # wildcard names of your original photos RENAME_FILES="PICT*.JPG pict*.jpg img_*.jpg IMG_*.JPG dsf*.jpg DSC*.JPG dsc*.jpg" # howto rename your files: img_1234.jpg --> 2006-08-13_230001_img_1234.jpg (image taken on 2006-08-13 23:00:01) JHEAD_OPTS="-n%Y-%m-%d_%H%M%S_%f" # paths setup: JHEAD="jhead" DCRAW="dcraw" EXIV2="exiv2" PPMTOJPEG="ppmtojpeg" ACPI="acpi" if [ ! -d $DEST ]; then mkdir -p $DEST; fi cd $DEST # lossless rotation of JPEG files do_rotation() { # {{{ rrfile="$1" degres="$2" echo -e "\t--> rotating $degres $rrfile" if jpegtran -rotate $degres -copy all -outfile ${rrfile}_tmp ${rrfile}; then echo -e "\t\tRotated" mv ${rrfile}_tmp ${rrfile} $EXIV2 -M'del Exif.Image.Orientation' $rrfile else echo -e "\t\tFailed" rm ${rrfile}_tmp fi } # }}} # distinguish angle of rotation rotate_jpeg() { # {{{ rfile="$1" orient=`$EXIV2 -P kyv $rfile | awk '/Exif.Image.Orientation/ { print $3; }'` case "$orient" in 1) echo "$rfile: Orientation: $orient top left"; ;; 6) echo "$rfile: Orientation: $orient right top"; do_rotation $rfile 90 ;; 8) echo "$rfile: Orientation: $orient left bottom"; do_rotation $rfile 270 ;; *) echo "$rfile: Orientation: $orient UNKNOWN"; ;; esac } # }}} # # mount, copy, umount # {{{ # # is memory card mounted? grep -q $MOUNTPOINT /etc/mtab if [ $? = 1 ]; then echo "Mounting $MOUNTPOINT" available_devs=`awk "\\$2 == \"$MOUNTPOINT\" { print \\\$1; }" /etc/fstab` if [ -z "$available_devs" ]; then echo "ERROR: mountpoint '$MOUNTPOINT' not found in /etc/fstab" exit 1; fi for dev in $available_devs; do if [ -e $dev ]; then echo "Mounting '$dev'" mount $dev break; fi done #mount $MOUNTPOINT make_umount="yes" fi count=1 # copy all files from memory card to destination folder for file in `find $MOUNTPOINT -type f -print`; do echo "$count: Copying file $file"; cp $file $DEST || exit 1 count=$(( count + 1)) done # if first parameter is 'remove', remove files from memory card if [ "x$1" = "xremove" ]; then echo "REMOVED REMOVED REMOVED start:"; find $MOUNTPOINT -type f -print -exec rm -f {} \; echo "REMOVED REMOVED REMOVED end:"; fi # umount CF, if was mounted by this script if [ "x$make_umount" = "xyes" ]; then echo "Umounting $MOUNTPOINT" umount $MOUNTPOINT fi # }}} # now rotate and rename your JPEG files from your CF card for ren in $RENAME_FILES; do rotate_jpeg $DEST/$ren $JHEAD $JHEAD_OPTS $DEST/$ren | while read jpg arrow newjpg; do mv ${jpg%.jpg}.CR2 ${newjpg%.jpg}.CR2 done done # if we are not on battery, do CPU expensive job - decode RAW files to JPEG, # add Exif info from thumbnail image *.thm to *.jpeg, rotate images, ... on_bat=`$ACPI 2>/dev/null | awk '/discharging/ { print $3; }'` if [ "x$on_bat" = "xdischarging," ]; then if [ "x$1" = "xremove" ]; then echo "On battery, do not decode RAW files" exit 0; fi fi find $DEST -maxdepth 1 -type f \( -name '*.CTG' -o -name '*.ctg' \) -ls -delete # decode raw files - CPU expensive job... echo "Decoding RAW files..." for i in img_*.crw img_*.cr2 IMG_*.CRW CRW_*.CRW IMG_*.CR2; do # {{{ [ "x$i" = "ximg_*.crw" ] && continue [ "x$i" = "ximg_*.cr2" ] && continue [ "x$i" = "xIMG_*.CRW" ] && continue [ "x$i" = "xCRW_*.CRW" ] && continue [ "x$i" = "xIMG_*.CR2" ] && continue small_i="`echo $i | tr '[A-Z]' '[a-z]'`" if [ "x$i" != "x$small_i" ]; then mv "$i" "$small_i"; # convert *.THM file to lowercase t="${i%.CRW}.THM" if [ -f "$t" ]; then small_t="`echo $t | tr '[A-Z]' '[a-z]'`" mv "$t" "$small_t" fi fi # file has been renamed to lowercase, change variable i="$small_i" ext="${i#*\.}" file="${i%.crw}" file="${file%.cr2}" if [ ! -f "$file.jpg" ]; then echo --- $i; $DCRAW -w $i # use white ballance set by camera $PPMTOJPEG $file.ppm > $file.jpg && rm -f $file.ppm ; fi # set EXIF information: rm -f $file.exv $file-thumb.jpg $EXIV2 ex $i [ -f $file.thm ] && ln -s $file.thm $file-thumb.jpg # doesn't work correctly #$EXIV2 -it $file.thm $file.jpg # use Exif info from *.thm file otherwise from *.crw file if [ -f "$file.thm" ]; then $EXIV2 -P kyv $file.thm | awk 'NF > 2 { print; }' | sed 's/^/set /g;' > $file.cmd else $EXIV2 -P kyv $i | awk 'NF > 2 { print; }' | sed 's/^/set /g;' > $file.cmd fi $EXIV2 -m $file.cmd $file.jpg # fix: Canon EOS 300D Digital Rebel stores wrong Exif.Image.Orientation info *.thm files # Exif.Image.Orientation needs to be read from RAW image #$EXIV2 -P kyv $file.crw | awk '/Exif.Image.Orientation/ { print; }' | sed 's/^/set /g;' > $file.cmd #$EXIV2 -m $file.cmd $file.jpg # rotate image if needed - we don't need rotate this JPEG file, because # orientation will be fixed if Exif.Image.Orientation Exif tag is removed. #rotate_jpeg $file.jpg # remove incorrect Exif headers (taken from thumbnail or after rotation) $EXIV2 \ -M'del Exif.Image.XResolution' \ -M'del Exif.Image.YResolution' \ -M'del Exif.Image.Orientation' \ $file.jpg # cleanup rm -f $file-thumb.jpg rm -f $file.exv rm -f $file.cmd # rename decoded *.jpg and RAW file too $JHEAD $JHEAD_OPTS $file.jpg | while read jpg arrow newjpg; do mv "${jpg%.jpg}.$ext" "${newjpg%.jpg}.$ext" t="${jpg%.jpg}.thm" [ -f "$t" ] && mv "$t" "${newjpg%.jpg}.thm" done done # }}} #echo "Removing unused *.thm files" #for i in *.thm; do # if [ ! -f "${i%.thm}.crw" ]; then # echo "$i removed" # rm -f $i; # fi #done # vim: fdm=marker fdl=0 fdc=3