11-18-2007

Everywhere Mag • imagefind.sh

I started playing around with a new travel site last week, Everywhere magazine. The site organizers collect user content in order to publish a travel magazine with featured destinations taken from the website. It’s very similar in format to JPG magazine, which is another creation from the folks at 8020 Publishing. The Everywhere site reminds me of Trek Earth, which attracts some incredible photography, but Everywhere has a bit more of a new-media flare to it. Plus, every destination is mapped out on a Google map, which will hopefully create for some very interesting geographic features in the future. I’d really like to see the concept of a ‘trip,’ where you link together various destinations all visited on the same trip, and are able to see the route plotted out on a map.

One problem that I’ve encountered (and it’s the same frustration that I had with JPG), is that any photo you upload to the site must be at least 2000 pixels in either height or width. I understand the requirement, seeing as how they’re actually looking to publish the photos, but it wipes out a large number of photos in my collection. When I was living in Ukraine and scrimping for extra space on my memory cards while traveling around, I would routinely downsize my pictures to 1600×1200, and now none of those pics are eligible for this site. In order to help myself find pics that do meet the 2000 pixel minimum, I wrote the following shell script (requires ImageMagick) which might also be useful to others:

#!/bin/sh
 
while getopts ":h:H:w:W:s:S:" opt; do
  case $opt in
    h ) min_height="$OPTARG"  ;;
    H ) max_height="$OPTARG"  ;;
    w ) min_width="$OPTARG"    ;;
    W ) max_width="$OPTARG"    ;;
    s ) min_size="$OPTARG"    ;;
    S ) max_size="$OPTARG"    ;;
  esac
done
shift $(($OPTIND - 1))
 
if [ -z "$1" ] ; then
  path="."
else
  path="$1"
fi
if [ -z $min_size ]; then
  min_size="0"
fi
if [ -z $max_size ]; then
  max_size="100000"
fi
 
for file in $(find $path -iname *.jpg -size +$min_size -size -$max_size | \
  sed '/ /d'); do
  stats=$(identify $file)
  width=$(echo $stats | awk '{print $3}' | awk -Fx '{print $1}')
  height=$(echo $stats | awk '{print $3}' | awk -Fx '{print $2}')
  if [ ! -z "$min_width" ]; then
    if [ "$width" -le "$min_width" ]; then
      continue
    fi
  fi
  if [ ! -z "$max_width" ]; then
    if [ "$width" -gt "$max_width" ]; then
      continue
    fi
  fi
  if [ ! -z "$min_height" ]; then
    if [ "$height" -le "$min_height" ]; then
      continue
    fi
  fi
  if [ ! -z "$max_height" ]; then
    if [ "$height" -gt "$max_height" ]; then
      continue
    fi
  fi
  echo $file
done

I haven’t had to write a shell script in awhile, and the one above is unnecessarily verbose (especially coming from Ruby), but it seems to do the trick. It sorta works like the find command, except that the options for the command precede the search path (which can be omitted, to search recursively from the current directory). It accepts any of the following six options:

As mentioned above, the script requires ImageMagick, specifically that the identify command is findable in your path. The script runs fairly slowly, as a result of using the identify command, which is why I’ve include the min-size flag. A lot of directories on my machine where photos are stored also contain thumbnails (such as my iPhoto library), and checking the width and height attributes for each thumbnail can get tedious. Hence, if you’re looking for photos that are at least 2000 pixels in width, you can probably assume that they’ll be at least 250K in size, thereby skipping the thumbnails and speeding up the script considerably:

imagefind.sh -w 2000 -s 250 europe/pics/

One feature the script doesn’t have that would be especially helpful when looking for Everywhere/JPG photos, is the ability to join the find options together with a -o (or) flag. Right now, each option passed to the script has to be satisfied in order for an image to be found, but it would be nice to find any images matching only one of multiple options, such as being at least 2000 pixels wide or 2000 pixels tall. As it stands now, that can only be accomplished with two separate invocations of the command.

And another major drawback is that the script doesn’t play well with spaces in file/directory names, so those are omitted entirely; I was just too lazy to fix it at the moment.