keep only 2 colors

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
haimnk

keep only 2 colors

Post by haimnk »

Hi

I'd like to replace all colors except for two. I know how to do it for one color with -fill and +opaque but couldn't figure out how to do it for two colors.

Any suggestions?

Thanks
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: keep only 2 colors

Post by fmw42 »

change the first color to a transparent. then change the second color as you are doing. then replace the transparent color to whatever you want
haimnk

Re: keep only 2 colors

Post by haimnk »

Thank you that makes sense but how do I replace transparent to color, all tutorials talk about color to transparent?
haimnk

Re: keep only 2 colors

Post by haimnk »

I did it like this now, many thanks:

Code: Select all

convert image.gif -fill black +opaque rgb(0,255,0) -transparent black  ( image.gif -fill black +opaque rgb(255,0,0) -transparent black ) -composite  result.gif
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: keep only 2 colors

Post by fmw42 »

You should be able to simplify yours by changing:

-fill black +opaque somecolor -transparent black

to

-fill none +opaque somecolor


Here is an alternate, but yours may be easier and more obvious for just two colors. I made a mask image that is transparent where the two colors are to be preserved and yellow where all the rest are to be changed. Then composited the mask over the original image.

Simple 5 color (red, magenta, green1, cyan, blue) image:
rmgcb.png
Image

Save only red and blue and make the rest yellow (simplified per Anthony's comment below):
convert rmgcb.png \
\( -clone 0 \
-transparent red \
-transparent blue \
-alpha extract \
-fill yellow -opaque white \
-transparent black \) \
-compose over -composite \
rmgcb_red_yellow_blue.png
Image

If you want to keep two colors and make the rest transparent, then this is a little easier (simplified per Anthony's comment below):
convert rmgcb.png \
\( -clone 0 \
-transparent red \
-transparent blue \
-alpha extract -negate \) \
-compose copy_opacity -composite \
rmgcb_red_none_blue.png
Image

You can extend either of these to more colors by simply adding one more line for each color:
-transparent somecolor
Last edited by fmw42 on 2009-04-23T09:53:19-07:00, edited 4 times in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: keep only 2 colors

Post by anthony »

fmw42 wrote:If you want to keep two colors and make the rest transparent, then this is a little easier.
convert rmgcb.png \
\( -clone 0 -channel rgba -alpha on \
-fill none -opaque red \
-fill none -opaque blue \
-alpha extract -negate \) \
-compose copy_opacity -composite \
rmgcb_red_none_blue.png
Image

You can extend either of these to more colors by simply adding one more line for each color:
-fill none -opaque somecolor
Nice solution: expanding the 'not this color' alternative technique, to create a 'not these colors'.

Another alternative is to just limit all changes to just the alpha channel, leaving the color channels AS IS. The -negate is still needed, but is also limited to negating the alpha channel, to flip what colors are visible.

Code: Select all

convert rmgcb.png \
         -channel A -transparent red -transparent blue -negate +channel \
         rmgcb_red_none_blue.png
Image
This removed the need for multiple images, parenthesis, and alpha composition.

As a side effect -transparent will automatically turn on the alpha channel, otherwise it is exactly the same as -alpha on -fill none -opaque somecolor



I'll update the example in 'fuzz factor' to use this improved solution.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: keep only 2 colors

Post by fmw42 »

Just as an aside, it might be nice to have a +transparent somecolor option to turn all colors but the one specified as transparent.

convert rgb.png +transparent red tmp.png
convert: unable to open image `red': No such file or directory @ blob.c/OpenBlob/2439.
haimnk

Re: keep only 2 colors

Post by haimnk »

Hi Guys,

There are a few issues:
fmw42 wrote:You should be able to simplify yours by changing:
-fill black +opaque somecolor -transparent black
to
-fill none +opaque somecolor
I'm actually converting the gifs to txt, and the suggested simplification takes about 5x longer than the other method. The file size also increases by about 15% as the output changes from

0,0: ( 0, 0, 0, 0) #00000000 none

to

0,0: ( 51, 51, 51, 0) #33333300 rgba(51,51,51,0)

for the transparent elements. The other color elements look also different (the text output I mean).
anthony wrote:

Code: Select all

convert rmgcb.png \
         -channel A -transparent red -transparent blue -negate +channel \
         rmgcb_red_none_blue.png
That looks so easy and I'd like to use this one as I need to keep 5 colors now but the original image already has transparent color in it and when I use the code above, the transparent becomes solid at the end. Is there a way of overcoming this? Btw, this method also takes 5x times longer when outputting to text.
haimnk wrote:

Code: Select all

convert image.gif -fill black +opaque rgb(0,255,0) -transparent black  ( image.gif -fill black +opaque rgb(255,0,0) -transparent black ) -composite  result.gif
I tried this one now for three colors but it didn't work? Just added another bracket command behind the first one but I guess that was wrong. How would I do that?

Many thanks
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: keep only 2 colors

Post by fmw42 »

I think you need to explain what you are really trying to do. We are shooting at a moving target!

What is the reason for the txt: format?

What do you want to happen with any already transparent pixels?

Are those pixels fully or partially transparent?

What do you want to see for all the other colors?

To fix Anthony's solution or mine, provided none of the colors you want to preserve are partially or fully transparent, add -alpha off after the input image:

convert rmgcb.png -alpha off \
-channel A -transparent red -transparent blue -negate +channel \
rmgcb_red_none_blue.png

If you want to keep doing what you have been, then -composite only works with two images at a time. But you can change that to -background somecolor -flatten. The background color can be whatever you want to show thru where there are transparent pixels. So it can be "none" if you want to keep them transparent or whatever other color you want to use

convert image.gif \
\( -clone 0 -fill black +opaque color-one -transparent black \) \
\( -clone 0 -fill black +opaque color-two -transparent black \) \
\( -clone 0 -fill black +opaque color-three -transparent black \) \
... etc ...
-delete 0 -background none -flatten result.gif

Note when using rgb colors, one often needs to enclose them in quotes, eg. "rgb(255,0,0)"

See http://www.imagemagick.org/script/color.php
Post Reply