Fred's ImageMagick Scripts


    Copyright © Fred Weinhaus

    My scripts are available free of charge for non-commercial (non-profit) use, ONLY.

    For use of my scripts in commercial (for-profit) environments or non-free applications, please contact me (Fred Weinhaus) for licensing arrangements. My email address is fmw at alink dot net.

    If you: 1) redistribute, 2) incorporate any of these scripts into other free applications or 3) reprogram them in another scripting language, then you must contact me for permission, especially if the result might be used in a commercial or for-profit environment.

    Usage, whether stated or not in the script, is restricted to the above licensing arrangements. It is also subject, in a subordinate manner, to the ImageMagick license, which can be found at:

    Please read the Pointers For Use on my home page to properly install and customize my scripts.


Finds the nearest color value in an image to a reference color.

Download Script

last modified: December 08, 2023

USAGE: nearestcolor [-c color] [-m mode] [-f fontname] [-p pointsize] [-l labelcolor] infile [outfile]
USAGE: nearestcolor [-h or -help]

-c .... color ............. reference color; any IM color specification; default=black
-m .... mode .............. mode to report color values; choices are 8bit or percent;
........................... default=8bit
-f .... fontname .......... fontname or path-to-font-file; default=Helvetic
-p .... pointsize ......... pointsize for font; default=18
-l .... labelcolor ........ color for label on output swatches; any IM color specification;
........................... default=white

If an outfile is provided, then the image produced will be a side-by-side set of color
swatches labeled with RGB values according to the mode selected.

PURPOSE: To find the nearest color value in an image to a reference color.

DESCRIPTION: NEARESTCOLOR finds the nearest color value in an image to a reference color. It will report the reference color and nearest color as an RGB triplet to the terminal in either 8bit (range 0 to 255) or percent (range 0 to 100%) according to the mode selected. If an output file is specified then a pair of side-by-side color swatches will be generated to compare the colors. The swatches will be labeled according to the fontname, pointsize and labelcolor specified. The swatch sizes will depend upon the pointsize and length of the label generated.


-c color ... COLOR is the reference color which will be used to find its nearest color in the image. Any valid IM text color may be used. The default is black. See

-m mode ... MODE is the mode used to display the RGB color values. The choices are: 8bit (range 0 to 255) or percent (range 0 to 100%). This will be used for display in the color swatches as well as to the terminal. The default is 8bit.

-f fontname ... FONTNAME is the desired font or path-to-font-file for the swatch labels. The default is Helvetica.

-p pointsize ... POINTSIZE is the desired pointsize for the swatch labels. The default is 18.

infile outfile ... If no outfile is provided, then the resulting nearest color and rmse metric will only be reported to the terminal. If an outfile is provided, then a pair of color swatches will be created, labeled and appended.

NOTE: This script requires IM 6.5.0-10 or higher due to the use of the new image matching feature in the compare function.

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.



-c red -m 8bit

-c red -m percent

What the script does is as follows:

  • Uses IM compare function to find the best match in the infile
    to a 1x1 pixel referenced colored image
  • Extracts the color of the matched pixel
  • Creates appended, labeled swatches for the refernce color and
    the matched color

This is equivalent to the following IM commands for the case of rgb in the range 0 to 255:

  • data=`compare -metric rmse -fuzz 1000000% $infile \( -size 1x1 xc:$color \) null: 2>&1`
  • coords=`echo "$data" | cut -d\ -f4`
  • xx=`echo "$coords" | cut -d, -f1`
  • yy=`echo "$coords" | cut -d, -f2`
  • rmse=`echo "$data" | sed -n 's/^.*[(]\(.*\)[)].*$/\1/p'`
  • rmse=`convert xc: -format "%[fx:floor(255*$rmse)]" info:`
  • mcolor=`convert ${infile}[1x1+${xx}+${yy}] -format \
    "rgb(%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)])" info:`
  • rcolor=`convert -size 1x1 xc:$color -format \
    "rgb(%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)])" info:`
  • echo ""
  • echo "RMSE Metric: $rmse"
  • echo "Reference Color: $rcolor"
  • echo "Nearest Image Color: $mcolor"
  • echo ""
  • convert \ \( -background "$rcolor" \
    -fill $labelcolor -font $fontname -pointsize $point \
    -gravity northwest label:"Reference Color:\n\n\n$rcolor" \) \
    \( -background "$mcolor" \
    -fill $labelcolor -font $fontname -pointsize $point \
    -gravity northwest label:"Nearest Color:\n\n\n$mcolor" \) \
    +append $outfile