Using GraphicsMagick or ImageMagick, how do I replace transparency with a fill colour?

Using GraphicsMagick, it's fairly easy to replace one colour with transparency...

gm convert -transparent magenta src.png dst.png

Unfortunately, I can't figure out a simple way to do the exact opposite. If I have an image file with alpha-channel transparency, how do I compose it on a constant-colour background then discard the now redundant alpha channel? The background colour should affect pixels that were partially transparent as well as fully transparent.

I've spotted the +matte option, but it literally discards the alpha layer - normally leaving junk colour pixels where the transparency was, rather than e.g. using the -background option to specify a background colour to use.

The only way I've managed this so far is using multiple calls - one to generate a solid-colour rectangle image file, another to composite the original image with the solid-colour image, and a third to discard the alpha channel. This seems crazy - surely it should be possible with a single fairly simple call?

I currently use GraphicsMagick, but there's no commitment - I'll switch to ImageMagick if it makes things easier.

EDIT

When I say "The background colour should affect pixels that were partially transparent as well as fully transparent.", I mean the result should be visibly what I would normally expect from blitting a transparent sprite onto a solid colour background. The partially transparent pixels should be blended.

This means that if I then reversed the process - turning the background colour key into transparency - I would expect to see a halo around the original image, where the background colour is blended into the pixels so the colour key doesn't precisely match and therefore isn't converted back to transparency. It's not what most people would want for that reason. It's what I want, though, as I won't be converting the background back to transparency - I'll still have the original image with the original transparency if I need it.


Using GraphicsMagick, -background color -extent 0x0 should be able to replace the first two steps in your process (for ImageMagick, it'd be -mosaic instead of -extent). I'm not sure about the third step, but it sounds like you're just running +matte on the image from the first two steps, so the final call would look something like this:

gm convert -background color -extent 0x0 +matte src.png dst.png

or for ImageMagick,

convert src.png -background color -mosaic +matte dst.png

What you're searching for almost fits the description of -opaque, but with a twist. Assuming a constant-color background, the command below might work for you (I only have ImageMagick to test on).

gm convert -channel matte -threshold 0% -channel RGB -fill [your background color] -opaque transparent -channel matte -threshold 100% src.png dst.png

-channel matte -threshold 0% sets pixels with any transparency to fully transparent, -channel RGB -fill [your background color] -opaque transparent replaces fully transparent pixels with the given fill color, and -channel matte -threshold 100% removes transparency from all pixels.