Skip to content

Instantly share code, notes, and snippets.

@grodtron
Created May 13, 2012 22:11
Show Gist options
  • Save grodtron/2690466 to your computer and use it in GitHub Desktop.
Save grodtron/2690466 to your computer and use it in GitHub Desktop.
A bash/ImageMagick script to recolor transparent .png files
#!/bin/bash
# A small script to change the color of mono-colored transparent .pngs
#
# Uses ImageMagick to read the most common 100% alpha color and then computes
# scale factors to multiply the whole image by.
#
# Improvements to be made:
# -deal with images containing pure black.
# -make portable between new and old ImageMagick versions
#########################################################
# #
# input validation #
# #
#########################################################
# make sure all command line arguments are actually given
if [ -z $1 ] || [ -z $2 ] || [ -z $2 ]
then
echo "Usage: $0 <color> <input file> <output file>"
exit 0
fi
# make sure the input file is a real file
if [ ! -e $2 ]
then
echo "Input file '$2' does not exist"
exit 0
fi
# make sure the input file can be read by us
if [ ! -r $2 ]
then
echo "Input file '$2' cannot be opened for reading"
exit 0
fi
# if the output file exists, make sure that we can write to it
if [ -e $3 ]
then
if [ ! -w $3 ]
then
echo "Output file '$3' cannot be opened for writing"
exit 0
fi
fi
newcolor=$1
infile=$2
outfile=$3
#########################################################
# #
# Normalize colors #
# #
#########################################################
if [[ "$newcolor" =~ 0x[0-9A-Fa-f]{6} ]]
then
# The color was given in a hex format, expand it to an array and convert to decimal
newcolors=($(sed 's/0x\(..\)\(..\)\(..\)/\1 \2 \3/' <<< "$newcolor"))
newcolors[0]=$(echo "ibase=16;obase=A;${newcolors[0]}" | bc)
newcolors[1]=$(echo "ibase=16;obase=A;${newcolors[1]}" | bc)
newcolors[2]=$(echo "ibase=16;obase=A;${newcolors[2]}" | bc)
# TODO - debugging, delete
echo "Color entered in hex, components are: R:${newcolors[0]}, G:${newcolors[1]}, B:${newcolors[2]}"
elif [[ "$newcolor" =~ [0-9]{1,3},[0-9]{1,3},[0-9]{1,3} ]]
then
# Color was entered in decimal, just convert to array
newcolor=($(sed 's/\(.\{1,3\}\),\(.\{1,3\}\),\(.\{1,3\}\)/\1 \2 \3/' <<< "$newcolor"))
# TODO - debugging, delete
echo "Color entered in hex, components are: R:${newcolors[0]}, G:${newcolors[1]}, B:${newcolors[2]}"
else
echo "Color is in an unknown format. Valid formats are hex: '0xNNNNNN' and dec: 'n,n,n'"
exit 0
fi
# Sample output from convert -colors command
#
# 601: (109,110,113,255) #6D6E71 rgba(109,110,113,1)
# .... more lines of the same
# Get the primary color in this .png
colors=($(convert $infile -colors 16 -depth 8 -format "%c" histogram:info: \
| sed -n 's/^.*(\([ 0-9]\{2\}[0-9]\),\([ 0-9]\{2\}[0-9]\),\([ 0-9]\{2\}[0-9]\),255).*$/\1 \2 \3/ p' \
| head -n1))
# Compute the scale factors to obtain the new colors from the old by multiplying
conversion[0]=$(echo "${newcolors[0]} / ${colors[0]}" | bc -l )
conversion[1]=$(echo "${newcolors[1]} / ${colors[1]}" | bc -l )
conversion[2]=$(echo "${newcolors[2]} / ${colors[2]}" | bc -l )
# TODO - debug, delete
echo "R: ${colors[0]} => ${newcolors[0]} (${conversion[0]})"
echo "G: ${colors[1]} => ${newcolors[1]} (${conversion[1]})"
echo "B: ${colors[2]} => ${newcolors[2]} (${conversion[2]})"
# TODO - Make portable between old and new versions of ImageMagick - This just requires checking the version
# and using either -recolor (old) or -color-matrix (new)
convert -recolor \
" ${conversion[0]}, 0, 0, 0, 0, \
0, ${conversion[1]}, 0, 0, 0, \
0, 0, ${conversion[2]}, 0, 0, \
0, 0, 0, 1, 0, \
0, 0, 0, 0, 1" \
$infile $outfile
@vsoch
Copy link

vsoch commented Aug 29, 2017

Try putting the hex in double quotes, single might parse it differently! I just tested and this worked for me :)
robot5
robot51

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment