Page 1 of 1

keep only 2 colors

Posted: 2009-04-22T00:41:05-07:00
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

Re: keep only 2 colors

Posted: 2009-04-22T10:29:37-07:00
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

Re: keep only 2 colors

Posted: 2009-04-22T14:49:11-07:00
by haimnk
Thank you that makes sense but how do I replace transparent to color, all tutorials talk about color to transparent?

Re: keep only 2 colors

Posted: 2009-04-22T15:03:55-07:00
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

Re: keep only 2 colors

Posted: 2009-04-22T16:04:12-07:00
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

Re: keep only 2 colors

Posted: 2009-04-22T20:38:37-07:00
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.

Re: keep only 2 colors

Posted: 2009-04-22T20:50:22-07:00
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.

Re: keep only 2 colors

Posted: 2009-04-23T12:47:12-07:00
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

Re: keep only 2 colors

Posted: 2009-04-23T15:21:45-07:00
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