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.


Maps or translates one set of colors in an image to another set of colors.

Download Script

last modified: December 15, 2018

USAGE: mapcolors [-f file] [-s safecolor] [-m] [-a] [-d depth] [-t type] infile outfile
USAGE: mapcolors [-help]

-f .... file ............. Space delimited text file containing "from" and "to" colors;
.......................... Any valid IM color is allowed;
-s .... safecolor ........ Any color not used in the image; To be used as intermediary color;
.......................... Any valid IM color is allowed including none;
.......................... The default=none
-m ....................... Monitors the progess by printing a comment to the terminal for
.......................... every color processed.
-a ....................... Disables transparency for the output image; Values are on or off;
.......................... The default leaves it as determined by the input image and processing.
-d .... depth ............ Desired depth for output image, relevant to your IM Q level.
.......................... default is to leave it according to the input and processing.
-t .... type ............. Type forces the resulting image class to be either:
.......................... palette or palettematte. The default is the leave the image class
.......................... as determined by the input image and the processing.

PURPOSE: Maps or translates one set of colors in an image to another set of colors.

DESCRIPTION: MAPCOLORS maps (or translates or changes) one set of colors in an image to another set of colors. The color pairs must be provided in a text file as a "from" color separated by one or more space followed by a "to" color, one pair per row in the file.


-f file ... File containing space delimeted pairs of colors, one pair per row. The first color will be mapped or changed to the second color using a safecolor as intermediary. Any valid IM color is allowed such that it does not include the safecolor. See

-s safecolor ... SAFECOLOR is the safe color to use as the intermediary in the mapping process. It must not a color that exists already in the input image. Any valid IM color is allowed. See For mapping colors that do not include transparency, use the default=none, but do not use none for any "from" or "to" color in the file. If you want to change transparnent colors, then you need to find some other non-used color in the image for the safecolor.

-m ... Enables progress monitoring by printing each color change to the terminal as it is processed. Use this when you have a large number of colors to map, since process is rather slow depending upon image size and number of colors to change.

-a ... Disables transparency in the resulting image. Use only if you know there are no transparent colors left or created in the output image. The default is to leave the transparency as determined by the input image and the processing.

-d depth ... Depth is the depth of the resulting image. Allowed values depend on the IM Q level of your IM build. You may set the depth to the smalles value that will account for all the colors in your image. The default is to leave it as determined by the input image's depth and processing.

-t type ... TYPE controls the image class of the resulting image. The default is to leave the image class unchanged. Other choices are palette or palettematte. They will force the image class to be pseudoclass rather than directclass. For some image formats and processing this can lead to smaller file sizes, but in other cases it appears that leaving it unchanged results in smaller files sizes. You may have to play with this for your image format.

Note: This script probably will not work for versions of IM prior to due to a bug in +opaque

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.


Rearrange Three Non-Transparent Colors
red to green
green to blue
blue to red

Original Image

-f colors.txt -s none -d 8 -a

Rearrange Three Colors --- No Change To Middle Transparent Color
red to blue
blue to red

Original Image

-f colors3.txt -s black -d 8

Rearrange Three Colors --- Change Middle Transparent Color To Non-Transparent Color
red to blue
none to green1
blue to red

Original Image

-f colors4.txt -s black -d 8 -a -t palette

Map Grayscale Image To Rainbow Image
256 (RGB) Grayscales Mapped To 256 HSL Colors

Original Image

-f colors2.txt -s none -d 8 -a

What the script does is as follows for safecolor=none:

  • Convert the file to a string and then a list and then an array of color pairs
  • Create a completely transparent temporary image the size of the input
  • For each color pair
    • Separate "from" and "to" colors
    • Convert input to a temporary with all "non-from" colors changed to
      transparent "none" and all "from" color changed to "to" color
    • Composite the new temporary with the old temporary
  • Composite the final temporary over the input

This is equivalent to the following IM commands:

  • ww=`convert $tmpA -ping -format "%w" info:`
  • hh=`convert $tmpA -ping -format "%h" info:`
  • convert -size ${ww}x${hh} xc:none $tmp0
  • color_list=`cat $colors_file`
  • color_list=`echo "$color_list" | sed 's/[ ][ ]*/ /g; s/^[ ]\(.*\)$/\1/; s/[,][ ]/,/g; s/ /:/g'`
  • colorArray=($color_list)
  • for colorpair in ${colorArray[*]}; do
  • color1=`echo "$colorpair" | cut -d: -f1`
  • color2=`echo "$colorpair" | cut -d: -f2`
  • convert \( $tmpA -channel rgba -alpha on \
    -fill none +opaque "$color1" \
    -fill "$color2" -opaque "$color1" \) $tmp0 \ -composite $tmp0
  • done
  • convert $tmpA $tmp0 -composite $bitdepth $transparent $otype $outfile