#!/bin/bash set -euo pipefail usage() { echo "Usage: $0 [] " echo echo "Options:" echo " -h Print this help." echo " -c Highlight differences with this color; defaults to red." echo " -e Show Exif differences only; don't compare the image data." echo " -f Use the specified percentage of fuzz. Defaults to " echo " 5% for JPEGs, zero otherwise." echo " -n The name to give the first file." echo " -N The name to give the second file." echo } color= exif_only=false fuzz= name1= name2= while getopts "hc:ef:n:N:" opt do case "$opt" in h) usage exit 0 ;; c) color="$OPTARG" ;; e) exif_only=true ;; f) fuzz="$OPTARG" ;; n) name1="$OPTARG" ;; N) name2="$OPTARG" ;; esac done shift $(( OPTIND - 1 )) if [ -z "${1-}" ] || [ -z "${2-}" ] then usage exit 1 fi f1="$1" f2="$2" if [[ "$f1" != '/dev/null' ]] && [[ ! -f "$f1" ]] then echo "$f1: No such file." >&2 exit 1 fi if [[ "$f2" != '/dev/null' ]] && [[ ! -f "$f2" ]] then echo "$f2: No such file." >&2 usage exit 1 fi if [[ -z "$name1" ]] then name1="$f1" fi if [[ -z "$name2" ]] then name1="$f2" fi ext="${name1##*.}" if diff "$f1" "$f2" >/dev/null then exit 0 fi exif() { if [[ "$1" = /dev/null ]] then echo /dev/null return fi local b="$(basename "$1")" local d="$(mktemp -t "$b.XXXXXX")" exiftool "$1" | grep -v 'File Name' | \ grep -v 'Directory' | \ grep -v 'ExifTool Version Number' | \ grep -v 'File Inode Change' | \ grep -v 'File Access Date/Time' | \ grep -v 'File Modification Date/Time' | \ grep -v 'File Permissions' | \ grep -v 'File Type Extension' \ >"$d" echo "$d" } diff_clean_names() { diff -u "$1" --label "$name1" "$2" --label "$name2" || true } if which exiftool > /dev/null then d1="$(exif "$f1")" d2="$(exif "$f2")" diff_clean_names "$d1" "$d2" else diff_clean_names "$f1" "$f2" fi if $exif_only then exit 0 fi if \ ! which compare > /dev/null || \ ! which montage > /dev/null then echo 'ImageMagick is not installed.' >&2 exit 1 fi if compare "$f1" "$f2" /dev/null then exit 0 fi bn="$(basename "$f1")" destfile="$(mktemp -t "$bn.XXXXXX").png" if [ -z "$fuzz" ] && ( [ "$ext" = "jpeg" ] || [ "$ext" = "jpg" ] ) then fuzz='5' fi color_flag= if [ -n "$color" ] then color_flag="-highlight-color $color" fi fuzz_flag= if [ -n "$fuzz" ] then fuzz_flag="-fuzz $fuzz%" fi compare $color_flag $fuzz_flag "$f1" "$f2" png:- | \ montage -geometry +4+4 "$f1" - "$f2" png:- >"$destfile" 2>/dev/null || true if which xdg-open > /dev/null then xdg-open "$destfile" else open "$destfile" fi