Because creating images that the open source PBX Asterisk(tm) will properly fax using the SendFAX() application, was a pain in the ass, I'd like to share my findings.

The HOWTO for creating TIFF images that are laid out so the spandsp fax back-end in asterisk, is embedded in the images2fax.sh shell script, below.

In short, you need to have images of 1728x2292, in 2 colors, with the correct DPI (204x196) and the right compression.

This script automates the process of scaling, resizing, adding canvas and merging more images into a single multi-page image. It takes two or more arguments: the destination TIFF and all source images. It uses the multi-purpose ImageMagick convert utility for all the necessary operations.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
#!/bin/sh
# images2fax.sh -- Walter Doekes 2010
# vim: set ts=8 sw=4 sts=4 et:

#
# Get arguments / show help
#

IMCONVERT="`which convert`"
if [ "$#" -lt 2 -o -z "$IMCONVERT" ]; then
    cat >&2 << __EOF__
Usage: $0 OUTPUT.TIFF INPUT.IMG...
Converts a collection of input images to a single multipage tiff to be
sent using the asterisk SendFAX application.

Requires ImageMagick convert(1), found at: ${IMCONVERT:-NOT FOUND}
__EOF__
    exit 1
fi
OUTPUT="$1" ; shift


#
# Utility functions
# (mktemp and mktemp_tiff return filenames safe to use without double quotes)
#

mktemp_tiff() {
    # Bah, this is ugly.
    file=`mktemp`
    mv -n $file $file.tiff
    if [ $? = 0 ]; then
        file=$file.tiff
    else
        rm $file
        file=`mktemp_tiff` # filename in use? try again
    fi
    echo $file
}

resize_image_to_1728x2292() {
    input="$1"
    output=`mktemp_tiff`
    # (-alpha: remove transparency)
    # (-resample: scale to correct proportions)
    # (-scale: resize up/down so it fits)
    # (-extent: add white canvas)
    "$IMCONVERT" "$input" -alpha off -resample 204x196 -scale 1728x2292 \
        -extent 1728x2292 $output
    if [ $? != 0 ]; then
        rm $output
        exit 1
    fi
    echo $output
}

convert_image_to_tiff() {
    input="$1"
    output=`mktemp_tiff`
    "$IMCONVERT" "$input" -compress Fax -units PixelsPerInch -density 204x196 \
        -antialias -resize '1728x2292!' -dither FloydSteinberg -monochrome \
        -dither FloydSteinberg -monochrome $output
    if [ $? != 0 ]; then
        rm $output
        exit 1
    fi
    echo $output
}


#
# Main: convert individual images and combine them
#

converted_list=""
for image in $@; do
    # Resize image
    resized=`resize_image_to_1728x2292 "$image"`
    if [ $? != 0 ]; then
        echo "Failure resizing $image. Aborting..." >&2
        [ -n "$converted_list" ] && rm $converted_list
        exit 1
    fi

    # Convert image
    converted=`convert_image_to_tiff $resized`
    if [ $? != 0 ]; then
        echo "Failure converting $image. Aborting..." >&2
        rm $converted_list $resized
        exit 1
    fi

    # Append to list
    rm $resized
    converted_list="$converted_list $converted"
done

"$IMCONVERT" '(' -coalesce $converted_list ')' "$OUTPUT"
status=$?
rm $converted_list
exit $status

Update 2010-12-06

In some cases — this has been observed when converting PDF to TIFF — the polarity can be mixed up, creating a white-on-black fax which can be quite expensive ;-) Fix this using the -define quantum:polarity=min-is-white option.

code bash