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
keep only 2 colors
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: keep only 2 colors
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
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
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
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: keep only 2 colors
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
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
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
You can extend either of these to more colors by simply adding one more line for each color:
-transparent somecolor
-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
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
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
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.
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: keep only 2 colors
Nice solution: expanding the 'not this color' alternative technique, to create a 'not these colors'.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
You can extend either of these to more colors by simply adding one more line for each color:
-fill none -opaque somecolor
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
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/
https://imagemagick.org/Usage/
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: keep only 2 colors
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.
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
Hi Guys,
There are a few issues:
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).
Many thanks
There are a few issues:
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 fromfmw42 wrote:You should be able to simplify yours by changing:
-fill black +opaque somecolor -transparent black
to
-fill none +opaque somecolor
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).
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.anthony wrote:Code: Select all
convert rmgcb.png \ -channel A -transparent red -transparent blue -negate +channel \ rmgcb_red_none_blue.png
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?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
Many thanks
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: keep only 2 colors
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
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