t* Simple Justified Gallery
       
   URI git clone git://git.codevoid.de/mkpicindex
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
       tmkpicindex-static.sh (7380B)
       ---
            1 #!/bin/sh
            2 
            3 printf '%s' \
            4 '/*!
            5  * mkpicindex.sh - v0.1
            6  * https://codevoid.de
            7  * Copyright (c) 2019 Stefan Hagen
            8  * Licensed under the ISC license.
            9  */
           10 ' > LICENSE
           11 
           12 # DEPENDENCIES
           13 # - ImageMagic (identify, convert)
           14 # - raw only: jhead
           15 # - raw only: dcraw
           16 
           17 # LIMITATIONS
           18 # - leftover images on the last row won't be added
           19 # - the thumbnail cache is not cleaned automaticall
           20 
           21 
           22 # CONFIGURE
           23 TITLE="My Gallery"          # browser title
           24 WIDTH=1000                  # how wide will the gallery be
           25 ROW_HEIGHT=180              # how high will the justified rows be?
           26 THUMB_QUALITY=83            # quality for thumbnails
           27 THUMB_PATH="thm"            # relative path to thumbnail folder
           28 THUMB_PADDING="6"           # image padding
           29 
           30 # TECHNICAL STUFF
           31 DEBUG=0                     # debug output
           32 PROCS=8
           33 
           34 # PRINT HELP / USAGE TEXT
           35 usage() {
           36     printf '%s\n' \
           37 'mkpicindex - Version: $Id$
           38 
           39 Usage: mkpicindex [arguments] > file.html
           40 
           41 Arguments:
           42   -t "My Gallery" Gallery title
           43   -w 850          Gallery main area width
           44   -h 180          Row height (thumbnail size)
           45   -q 83           Thumbnail quality
           46   -b 6            Thumbnail border (padding)
           47   -p 8            Max. parallel conversion processes
           48   -d              Enable debug mode (verbose output)
           49   -h              Usage (this text)
           50 '
           51     exit 2
           52 }
           53 
           54 # OVERIDE DEFAULTS
           55 while getopts 't:w:h:b:q:p:d' c
           56 do
           57   case $c in
           58     t) TITLE="$OPTARG" ;;
           59     w) WIDTH="$OPTARG" ;;
           60     h) ROW_HEIGHT="$OPTARG" ;;
           61     q) QUALITY="$OPTARG" ;;
           62     b) THUMB_PADDING="$OPTARG" ;;
           63     p) PROCS="$OPTARG" ;;
           64     d) DEBUG=1 ;;
           65     ?|*) usage; ;;
           66   esac
           67 done
           68 
           69 # PRINT USAGE IF OUTPUT IS NOT REDIRECTED
           70 [ "$DEBUG" != 1 ] && test -t 1 && usage;
           71 
           72 # GLOBAL TMP VARIABLES
           73 G_ROW_WIDTH=0               # combined pic width   < WIDTH @ ROW_HEIGHT
           74 G_ROW_FILES=""              # pipe separated files < WIDTH
           75 MORE=1                      # trigger next loop
           76 
           77 # CREATE THUMBNAIL DIRECTORY
           78 mkdir -p "$THUMB_PATH"
           79 
           80 # OUTPUT HELPER
           81 debug() { [ "$DEBUG" == "1" ] && printf '%s\n' "Debug: $1" >&2; }
           82 console() { printf '%s\n' "$1" >&2; }
           83 
           84 # CALCULATE BY ASPECT RATIO
           85 get_width_by_height() {
           86     # returns aspect ratio calculated width
           87     local F="$1"  # image file
           88     local TH="$2" # target height
           89     local R="$(identify -format ' %w %h ' "$1" | awk -vTH=$TH \
           90                                      '{ printf("%.0f", TH*($1/$2)) }')"
           91     printf '%.0f' "$R"
           92     debug "get_width_by_height: FILE=$F TARGET_HEIGHT=$TH RET_WIDTH=$R"
           93 }
           94 
           95 # TOO MANY CONVERT PROCSSES => WAIT
           96 thread_check() { 
           97     while [ $(pgrep convert | wc -l | awk '{ print $1 }') -gt $(($PROCS-1)) ];
           98     do debug "Process Limit ($PROCS) reached. Waiting..."; sleep 2; done
           99 }
          100 
          101 # EXTACT CAMERA IMAGE FROM RAW
          102 convert_raw() {
          103     # XXX dcraw may export a PPM file.
          104     F="$1" # raw image
          105     if ! [ -f "${F%%.*}_preview.jpg" ]; then
          106         dcraw -e -c "$F" > "${F%%.*}_preview.jpg"
          107         jhead -q -autorot "${F%%.*}_preview.jpg"
          108         console "Raw Conversion: ${F%%.*}_preview.jpg"
          109     fi
          110 }
          111 
          112 # CREATE THUMBNAIL
          113 create_thumb() {
          114     local F="$1" # original
          115     local W="$2" # width
          116     local H="$3" # height
          117     local T="${F%%.*}-$H"
          118     if [ -f "$THUMB_PATH/$T.gif" ]; 
          119         then printf '%s' "$THUMB_PATH/$T.gif"
          120     elif [ -f "$THUMB_PATH/$T.jpeg" ];
          121         then printf '%s' "$THUMB_PATH/$T.jpeg"
          122     else
          123         thread_check
          124         case $(printf '%s' "${F##*.}" | tr '[:upper:]' '[:lower:]') in
          125             gif) console "Creating Thumbnail: $THUMB_PATH/$T.gif"
          126                  nohup convert -quality $THUMB_QUALITY -sharpen 2x2 \
          127                          -coalesce -resize 6000x$H\> \
          128                          -deconstruct "$F" \
          129                          "$THUMB_PATH/$T.gif" >/dev/null 2>&1 &
          130                  printf '%s' "$THUMB_PATH/$T.gif" ;;
          131              *)  console "Creating Thumbnail: $THUMB_PATH/$T.jpeg"
          132                  nohup convert -quality $THUMB_QUALITY -sharpen 2x2 \
          133                                -auto-orient -resize 6000x$H\> "$F" \
          134                           "$THUMB_PATH/$T.jpeg" >/dev/null 2>&1 &
          135                  printf '%s' "$THUMB_PATH/$T.jpeg" ;;
          136         esac
          137     fi
          138 }
          139 
          140 # ADD IMAGE LOOP
          141 add_image() {
          142     local F="$1" # image file
          143     # How wide would the image be when we rescale it to $ROW_HEIGHT?
          144     local NW=$(get_width_by_height "$F" "$ROW_HEIGHT")
          145     debug "add_image: FILE=$F NW=${NW}x$ROW_HEIGHT"
          146 
          147     # We add images and their width to $G_ROW_WIDTH until $WIDTH will
          148     # be exceeded.
          149     if [ "$(( $G_ROW_WIDTH + $NW ))" -gt "$WIDTH" ]; then
          150 
          151         debug "add_image: max width reached with F=$F @ $G_ROW_WIDTH"
          152 
          153         # we're building a row now
          154         printf "        <div class=\"row\">\n";
          155 
          156         # calculate how much we need to stretch images to fill the
          157         # whole row.
          158         local RFH=$(printf "$G_ROW_WIDTH $WIDTH $ROW_HEIGHT" \
          159             | awk '{ printf("%.0f",$3*($2/$1)) }')
          160         debug "RFH=$RFH"
          161 
          162         # loop through the images in this row and recalculate
          163         # them with their new, real height.
          164         local IFS='|'; for RF in $G_ROW_FILES;
          165         do
          166             local RFW=$(($(get_width_by_height "$RF" "$RFH") - 2*$THUMB_PADDING))
          167             debug "add_image: adding file: F=$RF with W=$RFW H=$RFH"
          168 
          169             local T=$(create_thumb "$RF" "$RFW" "$RFH")
          170             debug "add_image: created thumbnail $T"
          171 
          172             # output HTML for image
          173             console "Adding Image: $RF"
          174             printf '            <div class="image">\n'
          175             printf '                <a href="'$RF'">\n'
          176             printf '                    <img width="'$RFW'" height="'$RFH'" src="'$T'">\n'
          177             printf '                </a>\n'
          178             printf '            </div>\n'
          179         done
          180 
          181         # we're done with this row now.
          182         printf "        </div>\n";
          183 
          184         # set leftover file as for next iteration
          185         G_ROW_WIDTH="$NW"
          186         G_ROW_FILES="$F|"
          187     else
          188         # add more items...
          189         debug "add_image: width has not been reached, continue loop."
          190         G_ROW_WIDTH="$(( $G_ROW_WIDTH + $NW ))"
          191         G_ROW_FILES="$F|$G_ROW_FILES"
          192     fi
          193 }
          194 
          195 # HEADER
          196 printf '%s\n' \
          197 '<html>
          198     <head>
          199     <meta name="viewport" content="width=device-width">
          200     <title>'"$TITLE"'</title>
          201         <style>
          202         html {
          203             background: black;
          204             color: orange;
          205         }
          206         .base {
          207             margin-left: auto;
          208             margin-right: auto;
          209             width: min-content;
          210         }
          211         .row {
          212             display: block;
          213             float: clear;
          214             width: max-content;
          215             margin-left: auto;
          216             margin-right: auto;
          217             white-space: nowrap;
          218         }
          219         .image {
          220             float: left;
          221             width: fit-content;
          222             height: fit-content;
          223             padding: '"$THUMB_PADDING"';
          224         }
          225         </style>
          226     </head>
          227     <body>
          228         <div class="base">
          229 '
          230 ### MAIN LOOP ##########################################################
          231 for F in *.*;
          232 do
          233     if [ -f "$F" ];
          234     then
          235         case "$(printf '%s' ${F##*.} | tr '[:upper:]' '[:lower:]')" in
          236             jpg|jpeg|png|gif) add_image "$F" ;;
          237             cr2|dng|nef)      convert_raw "$F" && \
          238                               add_image "${F%%.*}_preview.jpg" ;;
          239             *)                console "Ignoring: $F" ;;
          240         esac
          241     fi
          242 done
          243 ### MAIN LOOP END ######################################################
          244 
          245 # FOOTER
          246 printf '%s\n' \
          247 '       </div> 
          248     </body>
          249 </html>'