#!/bin/sh printf '%s' \ '/*! * mkpicindex.sh - v0.1 * https://codevoid.de * Copyright (c) 2019 Stefan Hagen * Licensed under the ISC license. */ ' > LICENSE # DEPENDENCIES # - ImageMagic (identify, convert) # - raw only: jhead # - raw only: dcraw # LIMITATIONS # - leftover images on the last row won't be added # - the thumbnail cache is not cleaned automaticall # CONFIGURE TITLE="My Gallery" # browser title WIDTH=1000 # how wide will the gallery be ROW_HEIGHT=180 # how high will the justified rows be? THUMB_QUALITY=83 # quality for thumbnails THUMB_PATH="thm" # relative path to thumbnail folder THUMB_PADDING="6" # image padding # TECHNICAL STUFF DEBUG=0 # debug output PROCS=8 # PRINT HELP / USAGE TEXT usage() { printf '%s\n' \ 'mkpicindex - Version: $Id$ Usage: mkpicindex [arguments] > file.html Arguments: -t "My Gallery" Gallery title -w 850 Gallery main area width -h 180 Row height (thumbnail size) -q 83 Thumbnail quality -b 6 Thumbnail border (padding) -p 8 Max. parallel conversion processes -d Enable debug mode (verbose output) -h Usage (this text) ' exit 2 } # OVERIDE DEFAULTS while getopts 't:w:h:b:q:p:d' c do case $c in t) TITLE="$OPTARG" ;; w) WIDTH="$OPTARG" ;; h) ROW_HEIGHT="$OPTARG" ;; q) QUALITY="$OPTARG" ;; b) THUMB_PADDING="$OPTARG" ;; p) PROCS="$OPTARG" ;; d) DEBUG=1 ;; ?|*) usage; ;; esac done # PRINT USAGE IF OUTPUT IS NOT REDIRECTED [ "$DEBUG" != 1 ] && test -t 1 && usage; # GLOBAL TMP VARIABLES G_ROW_WIDTH=0 # combined pic width < WIDTH @ ROW_HEIGHT G_ROW_FILES="" # pipe separated files < WIDTH MORE=1 # trigger next loop # CREATE THUMBNAIL DIRECTORY mkdir -p "$THUMB_PATH" # OUTPUT HELPER debug() { [ "$DEBUG" == "1" ] && printf '%s\n' "Debug: $1" >&2; } console() { printf '%s\n' "$1" >&2; } # CALCULATE BY ASPECT RATIO get_width_by_height() { # returns aspect ratio calculated width local F="$1" # image file local TH="$2" # target height local R="$(identify -format ' %w %h ' "$1" | awk -vTH=$TH \ '{ printf("%.0f", TH*($1/$2)) }')" printf '%.0f' "$R" debug "get_width_by_height: FILE=$F TARGET_HEIGHT=$TH RET_WIDTH=$R" } # TOO MANY CONVERT PROCSSES => WAIT thread_check() { while [ $(pgrep convert | wc -l | awk '{ print $1 }') -gt $(($PROCS-1)) ]; do debug "Process Limit ($PROCS) reached. Waiting..."; sleep 2; done } # EXTACT CAMERA IMAGE FROM RAW convert_raw() { # XXX dcraw may export a PPM file. F="$1" # raw image if ! [ -f "${F%%.*}_preview.jpg" ]; then dcraw -e -c "$F" > "${F%%.*}_preview.jpg" jhead -q -autorot "${F%%.*}_preview.jpg" console "Raw Conversion: ${F%%.*}_preview.jpg" fi } # CREATE THUMBNAIL create_thumb() { local F="$1" # original local W="$2" # width local H="$3" # height local T="${F%%.*}-$H" if [ -f "$THUMB_PATH/$T.gif" ]; then printf '%s' "$THUMB_PATH/$T.gif" elif [ -f "$THUMB_PATH/$T.jpeg" ]; then printf '%s' "$THUMB_PATH/$T.jpeg" else thread_check case $(printf '%s' "${F##*.}" | tr '[:upper:]' '[:lower:]') in gif) console "Creating Thumbnail: $THUMB_PATH/$T.gif" nohup convert -quality $THUMB_QUALITY -sharpen 2x2 \ -coalesce -resize 6000x$H\> \ -deconstruct "$F" \ "$THUMB_PATH/$T.gif" >/dev/null 2>&1 & printf '%s' "$THUMB_PATH/$T.gif" ;; *) console "Creating Thumbnail: $THUMB_PATH/$T.jpeg" nohup convert -quality $THUMB_QUALITY -sharpen 2x2 \ -auto-orient -resize 6000x$H\> "$F" \ "$THUMB_PATH/$T.jpeg" >/dev/null 2>&1 & printf '%s' "$THUMB_PATH/$T.jpeg" ;; esac fi } # ADD IMAGE LOOP add_image() { local F="$1" # image file # How wide would the image be when we rescale it to $ROW_HEIGHT? local NW=$(get_width_by_height "$F" "$ROW_HEIGHT") debug "add_image: FILE=$F NW=${NW}x$ROW_HEIGHT" # We add images and their width to $G_ROW_WIDTH until $WIDTH will # be exceeded. if [ "$(( $G_ROW_WIDTH + $NW ))" -gt "$WIDTH" ]; then debug "add_image: max width reached with F=$F @ $G_ROW_WIDTH" # we're building a row now printf "
\n"; # calculate how much we need to stretch images to fill the # whole row. local RFH=$(printf "$G_ROW_WIDTH $WIDTH $ROW_HEIGHT" \ | awk '{ printf("%.0f",$3*($2/$1)) }') debug "RFH=$RFH" # loop through the images in this row and recalculate # them with their new, real height. local IFS='|'; for RF in $G_ROW_FILES; do local RFW=$(($(get_width_by_height "$RF" "$RFH") - 2*$THUMB_PADDING)) debug "add_image: adding file: F=$RF with W=$RFW H=$RFH" local T=$(create_thumb "$RF" "$RFW" "$RFH") debug "add_image: created thumbnail $T" # output HTML for image console "Adding Image: $RF" printf '
\n' printf ' \n' printf ' \n' printf ' \n' printf '
\n' done # we're done with this row now. printf "
\n"; # set leftover file as for next iteration G_ROW_WIDTH="$NW" G_ROW_FILES="$F|" else # add more items... debug "add_image: width has not been reached, continue loop." G_ROW_WIDTH="$(( $G_ROW_WIDTH + $NW ))" G_ROW_FILES="$F|$G_ROW_FILES" fi } # HEADER printf '%s\n' \ ' '"$TITLE"'
' ### MAIN LOOP ########################################################## for F in *.*; do if [ -f "$F" ]; then case "$(printf '%s' ${F##*.} | tr '[:upper:]' '[:lower:]')" in jpg|jpeg|png|gif|svg) add_image "$F" ;; cr2|dng|nef|CR2) convert_raw "$F" && \ add_image "${F%%.*}_preview.jpg" ;; *) console "Ignoring: $F" ;; esac fi done ### MAIN LOOP END ###################################################### # FOOTER printf '%s\n' \ '
'