Page 1 of 1

Simple subtract

Posted: 2010-05-25T06:05:44-07:00
by ralfbutler
Hi there,

I'm not very much into image processing. But I'm very interested in solving my current issue with ImageMagick.
I want to subtract B.gif
Image
from this image A.gif
Image
So, only the white, dark blue and green pixels should be left. Like this:
Image

But applying

Code: Select all

composite -compose subtract  A.gif B.gif C.gif
results in
Image
and

Code: Select all

composite -compose subtract  B.gif A.gif C.gif
results in
Image

It looks so me so simple. But the first result seems to be a combination of A and B, whereas the last result looks promising if the coloured pixels would have been copied out of A.
Any help is much appreciated!

Thanks,
Ralf

Re: Simple subtract

Posted: 2010-05-25T07:16:17-07:00
by snibgo
Imagemagick "subtract" is an arithmetical operation. So a white pixel minus a blue pixel is a yellow pixel. (Subtract three from ten: the result is neither three nor ten.)

You want:
- where two pixels are the same, the result should be black
- where they are different, you want the pixel from A.

This will do it. I create a mask d.png, which is transparent where the pixels are different, and black where they are the same. Then I simply place that mask over A.

Code: Select all

convert A.gif B.gif -compose subtract -composite -threshold 0.001 -negate -alpha copy -negate d.png

convert A.gif d.png -composite C.gif
The two commands can be combined, and there might be a more elegant/faster solution.

Re: Simple subtract

Posted: 2010-05-25T07:55:23-07:00
by snibgo
More elegant and faster:

Code: Select all

convert A.gif B.gif -compose Change-mask -composite d.png
convert -background black d.png -flatten C.gif

Re: Simple subtract

Posted: 2010-05-25T16:00:53-07:00
by ralfbutler
Awesome snibgo! Thanks a lot!

Re: Simple subtract

Posted: 2010-05-25T17:11:10-07:00
by anthony
I was about to suggest that too when I saw that snibgo already did.
Good work!

The change mask is the better solution and also understands the use of -fuzz to also match near-colors. However it is a 'boolean' transparency, Pixels are either left as is, or set to be transparent. Remember the 'destination' image (first image in "convert") is the one that will have its unchanged pixels preserved

You can however do it all in one command

Code: Select all

   convert A.gif B.gif -compose Change-mask -composite \
               -background black -flatten  C.gif
For more info. IM Examples, Compositing Images, Special Composition Methods, ChangeMask
http://www.imagemagick.org/Usage/compose/#changemask

This is also one of few compose methods which does not actually replace the colors within the
image. It only makes the colors transparent. However saving to GIF will loose that information.
That means an alternative way of setting the unchanged pixels to black is..

Code: Select all

   convert A.gif B.gif -compose Change-mask -composite \
               -background black -alpha background -alpha off  C.gif
See IM Examples, Basics, transparency Handling, Alpga Background
http://www.imagemagick.org/Usage/basics ... background

It was originally designed to convert unchanged colors to transparency, as a optimization for GIF Animations ( -layers OptimizeTransparency )
See IM examples, Gif Optimizations, Transparency Optimization
http://www.imagemagick.org/Usage/anim_opt/#opt_trans

Re: Simple subtract

Posted: 2010-05-25T18:46:37-07:00
by ralfbutler
Wow, ImageMagick is magic ;) Thanks anthony!!