Posted on November 10, 2017
Changing car colors with ImageMagick
I was asked by a colleague if it’s possible to replace the color of a stock car image with a different color using an automated script. I found that ImageMagick has the ability to replace black and white with different colors using the +level-colors filter, but it’s a dumb find-replace method which replaces all instances of white with red. You can see with the image below that it’s just not perfect.
Original image (includes a transparent background)
The first command I used tries to convert all black to black and all white to red.
The +level-colors command modifies black and white colors, converting them to the respective colors (‘black,red’ = black becomes black, white becomes red).
convert MX_Trasparent_Background.png +level-colors black,red MX_test.png
I didn’t like that because anything whitish turned red, including the chrome accents and black tires that had light grey highlights.
I realized that it is possible to create an image mask so that the changes don’t affect certain areas, but that would still require some effort from a developer. However that effort could be done once for every color of car, instead of many times.
First I had to get everything that wasn’t an alpha into its own channel.
convert MX_Trasparent_Background.png -alpha extract MX_mask.png
The following draws a circular mask in the masked image. A guess was made to position the circle as it’s pretty difficult to understand what “280,100 260,260” means in relation to the image (I didn’t take too long to research those parameters). If I were to do this for real, I would use a polyline to draw an area for the window and tires, not a simple circle.
convert MX_mask.png -fill black -draw "circle 280,100 260,260" MX_mask_bite.png
The next command uses the mask and the original image to create a new image with a bite taken out of it.
convert MX_Trasparent_Background.png MX_mask_bite.png -alpha Off -compose CopyOpacity -composite MX_bite.png
Following this, we have to change the whites to red.
convert MX_bite.png +level-colors black,red MX_test.png
Now that we have the red version with a bite mask in it, we can overlay it on the original image to get a red car except where the bite was taken out (this would be windows and tires, etc.)
convert MX_Trasparent_Background.png MX_test.png -compose multiply -layers flatten MX_final.png
A final note, this example used pure red for the color. It’s entirely possible to choose more subtle colors like Dark Burgundy Champagne Juliet Passion Fruit, or whatever car manufacturers are calling colors nowadays.