#!/bin/sh # genethumb.sh - Génération de thumbnails mortels de ta mère # # Programmes requis: # imagemagick : pour traiter les images # jhead : pour éliminer les infos EXIF des vignettes # gawk : pour connaître l'espace disque économisé grâce à jhead # # 3 Jan 1998: version 0.0.4 by Samuel Hocevar # # 22 May 2000: version 0.0.5 by Samuel Hocevar # # 15 Nov 2000: version 0.0.6 by Samuel Hocevar # with code from Sven Hartge # # 13 Dec 2000: version 0.0.7 by Samuel Hocevar # now compatible with old ImageMagick versions # added --rows option # # 27 Apr 2003: version 0.0.8 by Sam Hocevar removed all # bashisms now compatible with all ImageMagick versions # # 14 Jan 2006: version 0.0.9 by hugolino # convert changed its way to compute avi file # gôret-codage pour arranger ça # # 25 Fev 2006: version 0.0.9 by hugolino # Tri suivant le numéro de la photo (special thanks to JB on # fcou M-ID: <43ffb314$0$4055$626a54ce@news.free.fr> # # 17 Oct 2006: version 0.0.10 by hugolino # Joué avec identify pour afficher le temps d'exposition et # la vitesse # # 27 Aou 2007: Y'a(vait) un bug. Si les vignettes existent déjà, le temps # d'exposition, le diaph et la date ne sont pas extrait des # données EXIF J'ai aussi supprimé la création des fichiers # *.png.info # # 21 Avr 2008: version 0.3.0. # J'ai fait en sorte que l'index des photos en basse résolution # (préfixées par "ws_") et celui des photos en haute résolution, # utilise le même répertoire de mini_picts afin d'éviter que le # client réclame de nouvelles vignettes (qui étaient bien sûr les # mêmes). # Essayé d'optimiser les appels à identify. # TODO: Revoir la gestion des fichiers. Pour l'instant le script # ne teste pas s'il existe effectivement une version hi-res # de la photo ws_ # # 08 Mar 2009: version 0.3.1. # ImageMagick, dans sa version debian-lenny prend un malin plaisir # à ne plus lire les données purement EXIF des photos... Donc: # Utilisation de /usr/bin/exiftool du paquet debian libimage-exiftool-perl # pour récupérer les données EXIF avec un : # exiftool p1090429.jpg | grep "Create Date" | cut -b 35- # pour récupérer la date de création de la photo, et pareil pour # récupérer le diaph et la vitesse... # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Just go to a directory full of images, and launch genethumb.sh. It will # generate thumbnails and an index.html file for you. # # Another example: if you want to recursively run genethumb.sh in a # directory, try the following line: # for dir in `find -type d -name '.xvpics' -prune -o -print`; do ( cd "$dir" && genethumb.sh ) ; done # # You can choose the way this script sorts the images (either in alphabetical # order or according to the 4 last digits of the number included in the name of # the image, just use the search function of your editor to find the two lines # that begin whith "find", then comment out of the two lines. version=0.3.1 THFILE=index.php # index des tofs WebSizées --> préfixe : "ws_" THFILE_HIRES=hires.php # index des tofs en haute résolution THDIR=mini_picts # Répertoire où seront créés les thumbnails THEXT=jpg # change this to jpeg or whatever you want FONTSIZE=10pt NORMAL="" RED="" GREEN="" YELLOW="" BLUE="" MAGENTA="" CYAN="" WHITE="" # Marre des questions à 100 balles... DEFAULT_ANSWER_NICE="Y" # Ze bouzin will be niced to 19 by default DEFAULT_ANSWER_CSS_TO_USE="ZZZ" # E for external css, I for included css, neither of both will prompt user to choose MAKE_LINK_TO_HIRES="Y" # Pour gérer (mal) l'index des hi-res (cf TODO 21 Avr 2008) # Dimensions par défaut des thumbnails THWIDTH=240; THHEIGHT=180; ReponseSizeThumbnails=$1 echo ${RED} if [ `which figlet` ] then echo " GeneThumb" | figlet echo -n ${YELLOW} echo " ********" | figlet fi echo echo ${RED}" GeneThumb v ${YELLOW}$version${WHITE} auteur original : ${CYAN}Sam Hocevar" echo ${WHITE}" (report bugs to hugolino ${CYAN}${WHITE})" echo ${GREEN}" ____________________________________________________________" if test -z $1 >/dev/null then echo ${WHITE} echo " Ce programme génère une page html contenant les vignettes des photos" echo " présentes dans le répertoire." echo " Grâce à la CSS jointe, les vignettes sont incluses dans un tableau dont" echo " le nombre de colonnes dépend de la largeur de la fenêtre du navigateur." echo " (une liste utilisant la propriété \"float:left\")." echo echo ${GREEN} echo " Sélection de la taille des vignettes, (pour utiliser la dimension" echo " par defaut, (${CYAN}${THWIDTH}x${THHEIGHT}${GREEN}) tapez simplement la touche )" echo " ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯" echo " ${CYAN}Dimensions${GREEN} reconnues:"; echo " passer comme ${YELLOW}argument${GREEN}___"; echo " |"; echo ${WHITE}" o ${CYAN}96 x 72${WHITE} - - - - - - - > ${YELLOW}1"; echo ${WHITE}" o ${CYAN}120 x 90${WHITE} - - - - - - - > ${YELLOW}2"; echo ${WHITE}" o ${CYAN}160 x 120${WHITE} - - - - - - - > ${YELLOW}3"; echo ${WHITE}" o ${CYAN}200 x 150${WHITE} - - - - - - - > ${YELLOW}4"; echo ${WHITE}" o ${CYAN}240 x 180${WHITE} - - - - - - - > ${YELLOW}5"; echo ${WHITE}" o ${CYAN}256 x 256${WHITE} - - - - - - - > ${YELLOW}6"; echo echo ${WHITE}" o ${CYAN}Custom made${WHITE} - - - - - - > ${YELLOW}7"; echo ""; echo -n ${GREEN}" Choisissez la ${CYAN}dimension${GREEN} des vignettes (${YELLOW}1-7${GREEN}): "${YELLOW} read ReponseSizeThumbnails # la touche if test -z $ReponseSizeThumbnails >/dev/null then echo ${BLUE}" Aucune dimension sélectionnée, celle par défaut (${CYAN}${THWIDTH}x${THHEIGHT}${BLUE}) sera utilisée." fi fi ReponseSizeThumbnails="$(echo "$ReponseSizeThumbnails" | cut -b 1-1)" case "$ReponseSizeThumbnails" in 1) THWIDTH=96; THHEIGHT=72;; 2) THWIDTH=120; THHEIGHT=90;; 3) THWIDTH=160; THHEIGHT=120;; 4) THWIDTH=200; THHEIGHT=150;; 5) THWIDTH=240; THHEIGHT=180;; 6) THWIDTH=256; THHEIGHT=256;; 7) # WARNING: le user doit saisir la largeur et la hauteur echo "${GREEN}" echo " Vous avez choisi de saisir manuellement la largeur et ma hauteur utilisées" echo " pour dimensionner les vignettes.." echo echo ${RED}" Aucun contrôle n'est effectué sur les dimensions saisies." echo echo -n ${GREEN}" Choisissez la nouvelle ${YELLOW}largeur (en pixels)${GREEN} des vignettes : "${YELLOW} read Reponse THWIDTH=${Reponse}; echo -n ${GREEN}" Choisissez la nouvelle ${YELLOW}hauteur (en pixels)${GREEN} des vignettes : "${YELLOW} read Reponse THHEIGHT=${Reponse}; ;; esac if [ -r "$THFILE" ] then OldTitle=`grep "title" "$THFILE" | cut -d ">" -f 2 | cut -d "<" -f 1` echo echo ${GREEN}" Ancien titre de la page : "${MAGENTA}$OldTitle echo -n ${GREEN}" Pour changer le titre, saisissez-en un nouveau : ${YELLOW}" read Reponse TestReponse="x$Reponse" #echo "//$TestReponse//" if [ "$TestReponse" = 'x' ] then #Le_Repertoire=`basename $PWD` #echo "//$Le_Repertoire//" #TitrePage="Index of $Le_Repertoire" TitrePage=${OldTitle} else TitrePage="$Reponse" fi else echo -n ${GREEN}" Saisissez le titre de la page : ${YELLOW}" read Reponse TestReponse="x$Reponse" #echo "//$TestReponse//" if [ "$TestReponse" = 'x' ] then Le_Repertoire=`basename $PWD` #echo "//$Le_Repertoire//" TitrePage="Index of $Le_Repertoire" else TitrePage="$Reponse" fi fi if [ -d ${THDIR} ] then echo echo ${GREEN}" Le répertoire des vignettes (${CYAN}${THDIR}${GREEN}) existe déjà." echo -n ${GREEN}" Supprimer son contenu ? ${YELLOW}[o|N] " read Reponse Reponse="X"${Reponse} case ${Reponse} in Xo*|XO*) echo ${YELLOW}" 0K, suppression des vignettes dans ${CYAN}${THDIR}" rm -rf ${THDIR}"/tn_"* ;; X*|X*) echo ${YELLOW}" 0K, not doing it..." ;; esac else echo echo -n ${BLUE}" Création du répertoire des vignettes ${CYAN}${THDIR}${GREEN} : " if `mkdir ${THDIR}` then echo ${YELLOW}"OK" else echo ${RED}"Foired ... (exit)" echo ${NORMAL} exit 3 fi fi echo case "$DEFAULT_ANSWER_CSS_TO_USE" in I) echo ${BLUE}" Intégration de la css dans le fichier ${YELLOW} (DEFAULT_ANSWER_CSS_TO_USE=\"${RED}I${YELLOW}\")" CSS="I" ;; E) echo ${BLUE}" Utilisation de la css externe photos.css ${YELLOW} (DEFAULT_ANSWER_CSS_TO_USE=\"${RED}E${YELLOW}\")" echo ${BLUE}" Ajout d'un lien vers ${CYAN}/css/photos.css${BLUE}." CSS="E" ;; *) echo -n ${GREEN}" CSS : ${YELLOW}I${GREEN}nterne ou ${YELLOW}E${GREEN}xterne : ? ${YELLOW} [i/E] " read Reponse Reponse="X""$Reponse" case "$Reponse" in Xi*|XI*) CSS="I" ;; *) CSS="E" ;; esac ;; esac echo if [ $DEFAULT_ANSWER_NICE = "Y" ] then echo ${BLUE}" Nicage du bouzin ${YELLOW} (DEFAULT_ANSWER_NICE=\"${RED}Y${YELLOW}\")" NiceValue="19" else echo -n ${GREEN}" «Nicer» le bouzin ? ${YELLOW} [O/n] " read Reponse Reponse="X""$Reponse" case "$Reponse" in Xn*|XN*) NiceValue="0" ;; *) NiceValue="19" ;; esac fi Secondes_Debut=$(date +%s) echo if [ -w $THFILE ] then echo ${BLUE}" Sauvegarde de "${CYAN}"$THFILE"${BLUE}" sous le nom "${CYAN}"$THFILE~" mv -f $THFILE $THFILE~ fi if [ -w $THFILE_HIRES ] then echo ${BLUE}" Sauvegarde de "${CYAN}"$THFILE_HIRES"${BLUE}" sous le nom "${CYAN}"$THFILE_HIRES~" mv -f $THFILE_HIRES $THFILE_HIRES~ fi cat > $THFILE << EOF $TitrePage EOF if [ $CSS = "E" ] then cat >> $THFILE << EOF EOF else cat >> $THFILE << EOF EOF fi NbImages=`ls ws_*.jpg | wc -l` #NbImages=`ls *.jpg | wc -l` CommentNbImages=$NbImages" photos" cat >> $THFILE << EOF
EOF #cp $THFILE $THFILE_HIRES sed "s|$TitrePage|$TitrePage (hi-res)|" $THFILE > $THFILE_HIRES if [ $MAKE_LINK_TO_HIRES = "Y" ] then cat >> $THFILE << EOF EOF fi cat >> $THFILE << EOF

$TitrePage

$CommentNbImages
generated by GeneThumb version $version
(Merci Sam !)
High resolution photos

    EOF cat >> $THFILE_HIRES << EOF
      EOF ImgNum=0 compteur=1 created=0 ### ### ZE ULIMÊÊTE BOUCLE ### ### Choose either to sort numerically (first "find" line) or alphabetically (the second "find" line) ### echo # numerically sorting find ws_*.jpg -maxdepth 1 -type f | sed 's,\(.*[^0-9]\)\([0-9]\+\)\([^0-9]*\)$,\2 \1\2\3,' | sort -n | awk '{print $2}' | while read file # alphabetically sorting #find ws_*.jpg -maxdepth 1 -type f | sed 's,^\./,,' | while read file # le plus simple.... #for file in *.jpg do # on vérifie que l'image n'est pas déjà un thumbnail ou une page html, et a # une extension quelconque (à améliorer un peu) echo ${RED}" -=-=-" ImgNum="`expr 0$ImgNum + 1`" echo -n ${YELLOW}" "$ImgNum"/"$NbImages${GREEN}" Fichier "${CYAN}$file${GREEN}" :" case "$file" in *~|*.html|*.htm) echo ${GREEN}" skipping ..." ;; *) # Explication basename: # * retourne le nom du fichier passé en 1er argument sans l'extension passée en 2ème argument # * si $file=toto.jpg alors $newfile=toto # * si $file ne se termine pas par ".jpg" alors $newfile vaudra $file (il ne sera pas vide) # Puis on ajoute $THDIR et "tn_" devant et $THEXT derrière # ven jan 13 23:12:38 CET 2006 # Baisure !!! # Si je ne traite pas un toto.jpg mais un toto.avi alors newfile="toto.avi.$THEXT" mais # le convert toto.avi.$THEXT donne un toto.$THEXT, PAS un toto.avi.$THEXT... # Donc le test sur l'existence de toto.avi.$THEXT foire. # Donc le script en déduit que le convert a foiré alors que c'est basename qui foire # --> tester le code de retour de basename ou gérer le cas ou il est fait sur un .avi # pour ça: # Commenter la ligne ci dessous # newfile="$THDIR/tn_$(basename "$file" .jpg).$THEXT" # Si le convert est demandé comme convert toto.avi toto.png, ça foire car il créé autant de # toto.png-XYZ qu'il y a de frames dans toto.avi, donc il faut demander un # convert toto.avi toto.avi.png pour obtenir un toto.png (feature du nouvel ImageMagick ?) # Donc le $newfile passé à convert est tn_toto.png si on lui passe toto.jpg (et on obtiendra # bien un $newfile=toto.png" mais $newfile=tn_toto.avi.png si on lui passe toto.avi (et on # obtiendra un $newfile=tn_toto.png, donc ne pas utiliser newfile deux fois. BaseName=$(basename "$file" .jpg) if [ "$BaseName" = "$file" ] then # le fichier n'est pas un jpg BaseName=$(basename "$file" .avi) if [ "$BaseName" = "$file" ] then # le fichier n'est pas non plus un avi BaseName="Zob" echo -n ${RED}" Problème, ${CYAN}"$file"${RED} n'est pas un .jpg ou un .avi" else # le fichier est un avi FileType="avi" ArgumentConvert="$THDIR/tn_$BaseName.avi.$THEXT" ResultConvertFile="$THDIR/tn_$BaseName.$THEXT" fi else # le fichier est un jpg FileType="jpg" Suppress_ws_prefix=$(echo $BaseName | sed '-e s/ws_//') ArgumentConvert="$THDIR/tn_$Suppress_ws_prefix.$THEXT" ResultConvertFile=$ArgumentConvert fi if [ "$BaseName" = "Zob" ] then # le fichier n'est ni un jpg, ni un avi echo " : skipping it..." else # le fichier est soit un jpg, soit un avi failed=0 if [ -r "$ResultConvertFile" ] then echo ${RED}" NOT ${GREEN}replacing existing thumbnail." else nice -n $NiceValue convert -geometry ${THWIDTH}x${THHEIGHT} -quality 70 "$file" "$ArgumentConvert" >/dev/null 2>&1 if [ ! -r "$ResultConvertFile" ] then echo ${RED}" failed creating thumbnail." failed=1 else echo ${GREEN}" thumbnail créé." echo ${WHITE}" ---> "${CYAN}$ResultConvertFile${WHITE}" written." fi fi echo -n ${WHITE} # sam jan 14 01:40:28 CET 2006 # Fin correction if [ "$failed" = "0" ] then created="`expr 0$created + 1`" case "$FileType" in jpg) file_hires=$(echo $file | cut -b 4-) if [ -r "$file_hires" ] then file_hires_exist="Y" read Bytes_hires Width_hires Height_hires Junk << EOF `nice -n $NiceValue identify -format '%b %w %h' "$file_hires"` # | head -1 EOF Width_x_Height_hires=$Width_hires"x"$Height_hires KiloBytes_hires="`expr 0$Bytes_hires / 1024`" else file_hires_exist="N" fi read tn_Width tn_Height Junk << EOF `nice -n $NiceValue identify -format '%w %h' "$ResultConvertFile"` # | head -1 EOF tn_Width_x_Height=$tn_Width"x"$tn_Height read Bytes Width Height Junk << EOF `nice -n $NiceValue identify -format '%b %w %h' "$file"` EOF Width_x_Height=$Width"x"$Height # echo "Bytes : //"$Bytes"//" KiloBytes="`expr 0$Bytes / 1024`" # echo "KiloBytes : //"$KiloBytes"//" # if expr "$KiloBytes" ">" "1024" >/dev/null 2>&1 # then # MegaBytes="`expr 0$KiloBytes / 1024`" # fi # echo "Width_x_Height : //"$Width_x_Height"//" echo -n ${BLUE}" Size : ${CYAN}$Width${BLUE}x${CYAN}$Height${BLUE} (${CYAN}$KiloBytes ko${BLUE})" Date=`exiftool "$file" | grep "Create Date" | cut -b 35-` if [ ! "$Date" ] || [ "$Date" = 'unknown' ] || [ "$Date" = "0000:00:00 00:00:00." ] || [ "$Date" = ' ' ] then Date=`exiftool "$file" | grep "Date/Time Original" | cut -b 35-` if [ ! "$Date" ] || [ "$Date" = 'unknown' ] || [ "$Date" = "0000:00:00 00:00:00." ] then echo ${RED}" || ${BLUE}Date EXIF non enregistrée" Date="Date EXIF : N/A" else echo ${RED}" || ${BLUE}Date : ${CYAN}$Date" fi else echo ${RED}" ||${BLUE} Date : ${CYAN}$Date" fi Speed=`exiftool "$file" | grep "Shutter Speed" | cut -b 35-` if [ ! "$Speed" ] || [ "$Speed" = 'unknown' ] || [ "$Speed" = '' ] then Speed="N/A" fi echo -n ${BLUE}" Vitesse = ${CYAN}$Speed" Diaph=`exiftool "$file" | grep "^Aperture" | cut -b 35-` if [ ! "$Diaph" ] || [ "$Diaph" = 'unknown' ] || [ "$Diaph" = '' ] then Diaph="N/A" else Diaph="f/"$Diaph fi echo -n ${RED}" || ${BLUE}Diaph = ${CYAN}$Diaph" ISO=`exiftool "$file" | grep "^ISO" | cut -b 35-` if [ ! "$ISO" ] || [ "$ISO" = 'unknown' ] || [ "$ISO" = '' ] then ISO="N/A" fi echo ${RED}" || ${BLUE}ISO = ${CYAN}$ISO" ;; avi) read tn_Width tn_Height Junk << EOF `nice -n $NiceValue identify -format '%w %h' "$ResultConvertFile"` # | head -1 EOF tn_Width_x_Height=$tn_Width"x"$tn_Height ;; esac # écriture du commentaire sous le thumbnail #comment="`echo $file | cut -b1-43`" file_name="`echo $file | cut -b1-30`" if [ "$file" != "$file_name" ] then #file_name="`echo $file | cut -b1-40`..." file_name="`echo $file | cut -b1-27`..." fi if [ $file_hires_exist = 'Y' ] then file_name_hires="`echo $file_hires | cut -b1-30`" if [ "$file_hires" != "$file_name_hires" ] then #file_name_hires="`echo $file_hires | cut -b1-40`..." file_name_hires="`echo $file_hires | cut -b1-27`..." fi fi cat >> $THFILE << EOF
    • $file ($Width_x_Height)
      EOF if [ $file_hires_exist = 'Y' ] then cat >> $THFILE_HIRES << EOF
    • $file_hires ($Width_x_Height_hires)
      EOF fi case $FileType in jpg) # Watch out ! : Do not indent improperly the index file cat >> $THFILE << EOF $file_name
      $Width_x_Height ($KiloBytes ko)
      $Date
      Vitesse: $Speed
      Diaph: $Diaph ISO: $ISO
    • EOF if [ $file_hires_exist = 'Y' ] then cat >> $THFILE_HIRES << EOF $file_name_hires
      $Width_x_Height_hires ($KiloBytes_hires ko)
      $Date
      Vitesse: $Speed
      Diaph: $Diaph ISO: $ISO EOF fi ;; avi) cat >> $THFILE << EOF src="$ResultConvertFile">
      $comment
      Vidéo (320x240) EOF if [ $file_hires_exist = 'Y' ] then cat >> $THFILE_HIRES << EOF src="$ResultConvertFile">
      $comment
      Vidéo (320x240) EOF fi ;; esac fi fi esac done cat >> $THFILE << EOF
    EOF cat >> $THFILE_HIRES << EOF
EOF Secondes_Fin=$(date +%s) Secondes="`expr 0$Secondes_Fin - 0$Secondes_Debut`" AvgLoad=$(cut -d " " -f 2 /proc/loadavg) Footer_Comment="Page générée sur la machine `uname -n` le `date +"%a %d %B %Y"` à `date +"%Hh %Mm %Ss"` en $Secondes secondes. (Average load was $AvgLoad)" cat >>$THFILE << EOF
$Footer_Comment
EOF cat >>$THFILE_HIRES << EOF
$Footer_Comment
EOF echo ${RED}" -=-=-" echo if [ `which jhead` ] then cd ${THDIR} if [ $(basename $PWD) = ${THDIR} ] then echo ${GREEN}" Nettoyage des vignettes..." Size_THDIR_B=$(du -sk | gawk '{print $1}') jhead -purejpg tn_*jpg >/dev/null Size_THDIR_A=$(du -sk | gawk '{print $1}') echo -n ${GREEN}" Taille du répertoire ${CYAN}${THDIR}${GREEN} réduite de ${YELLOW}$Size_THDIR_B ko${GREEN} à ${YELLOW}$Size_THDIR_A ko" cd .. else echo ${RED}" Could not cd to ${CYAN}$PWD/${THDIR}" fi fi echo if [ `which figlet` ] then echo ${YELLOW} echo " Fini!!" | figlet else echo ${GREEN}" ___________" echo ${GREEN}" | |" echo ${GREEN}" | Fini!! |" echo ${GREEN}" |___________|" fi echo echo ${GREEN}" Durée ${YELLOW}$Secondes ${GREEN}secondes. Charge moyenne (5 min.) ${YELLOW}$AvgLoad" echo echo echo ${RED}" GeneThumb v ${YELLOW}$version${WHITE} auteur original : ${CYAN}Sam Hocevar" echo ${WHITE}" (report bugs to hugolino ${CYAN}${WHITE})" echo ${NORMAL} # vim:set ai et sts=4 sw=4 tw=180: