Hello all
I have 2 images:
1. sourceImage.png
2. colorPalette.png
I would like to replace all colours in sourceImage.png where they exist in colorPalette.png with RED. Is this possible in ImageMagick?
Thanks!
Jon
Replace all colours in image using another image
-
- Posts: 1
- Joined: 2018-10-15T17:23:35-07:00
- Authentication code: 1152
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Replace all colours in image using another image
I am not sure I understand. Imagemagick can replace the input colors with the nearest colors from the palette image. I am not sure where the red comes in. In any event please always provide your IM version and platform, if you already use it and your images. You may post to some free image hosting service such as dropbox.com that won't change your image format and put the URLs here.
Correct me if I am wrong. If your image contains exactly the same colors as in the palette, you want to write red to the image, no matter what the palette color is. Is that correct?
You could do that as follows, but it needs a bit of scripting. Here is a unix script:
# create image of several colors
convert -size 100x100 xc:black xc:red xc:yellow xc:green1 xc:cyan xc:blue xc:magenta +append image.png
# create palette from only red, green1 and blue
convert -size 10x10 xc:red xc:green1 xc:blue +append palette_rgb.png
# just to show the results of -unique-colors txt:
#So the next line filters that output to just retain the hex values in the colorList
If you want nearby colors that are slightly different from your palette colors to be red, then add -fuzz XX% before the -fill red.
Correct me if I am wrong. If your image contains exactly the same colors as in the palette, you want to write red to the image, no matter what the palette color is. Is that correct?
You could do that as follows, but it needs a bit of scripting. Here is a unix script:
# create image of several colors
convert -size 100x100 xc:black xc:red xc:yellow xc:green1 xc:cyan xc:blue xc:magenta +append image.png
# create palette from only red, green1 and blue
convert -size 10x10 xc:red xc:green1 xc:blue +append palette_rgb.png
# just to show the results of -unique-colors txt:
Code: Select all
convert palette_rgb.png -unique-colors txt:
Code: Select all
# ImageMagick pixel enumeration: 3,1,65535,srgb
0,0: (65535,0,0) #FF0000 red
1,0: (0,65535,0) #00FF00 lime
2,0: (0,0,65535) #0000FF blue
Code: Select all
colorList=$(convert palette_rgb.png -unique-colors txt: | tail -n +2 | sed 's/[ ][ ]*/ /g' | cut -d\ -f 3)
convert image.png new_image.png
for color in $colorList; do
convert new_image.png -fill red -opaque "$color" new_image.png
done
If you want nearby colors that are slightly different from your palette colors to be red, then add -fuzz XX% before the -fill red.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Replace all colours in image using another image
Doing this with a shell loop that reads "txt:" is the obvious method. The loop might build a command with many "-opaque" operations. But it can be done in a single magick command. Windows BAT syntax:
With large inputs and large palettes, this eats memory. We chop the palette into many 1x1 images and scale them all up to the image size. We find the difference of each of these with the main image. Each difference is black where the colour matches, so we make the others transparent, and change black to red. Lay all these over the original, and the job is done.
Code: Select all
magick ^
image.png +write mpr:ORIG ^
-set option:SIZE %%wx%%h ^
NULL: ^
( palette_rgb.png ^
-unique-colors ^
-crop 1x1 +repage ^
-scale "%%[SIZE]^!" ^
) ^
-compose Difference -layers composite ^
+transparent Black ^
-fill Red -colorize 100 ^
-background None ^
-layers Flatten ^
mpr:ORIG ^
-compose DstOver -composite ^
out.png
snibgo's IM pages: im.snibgo.com
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Replace all colours in image using another image
Another possibility is to crop the palette image into 1x1 images, and use "%[pixel:]" to create "-opaque" operations. Then include those operations in the main command.
This doesn't eat memory, runs "magick" only twice, and reads each input only once each.
Windows BAT syntax:
This doesn't eat memory, runs "magick" only twice, and reads each input only once each.
Windows BAT syntax:
Code: Select all
for /F "usebackq tokens=*" %%L in (`%IMG7%magick ^
palette_rgb.png ^
-unique-colors ^
-crop 1x1 +repage ^
-format "-opaque %%[pixel:p{0,0}] " ^
info:`) do set OPAQ=%%L
%IMG7%magick ^
image.png ^
-fill Red ^
%OPAQ% ^
out.png
snibgo's IM pages: im.snibgo.com