imagemagickpremultiplied-alpha

Compositing premultiplied images using ImageMagick


I have two images. One is background with no alpha. The other is a white cloud. The alpha of the cloud image is premultiplied with black. When I composite them the white cloud has black in it, so it looks grey instead of white like it should. I'm doing:

convert -gravity Center bg.tga whitecloud.tga -composite comp.tga

Is there a way to composite premultiplied images in ImageMagick, or does the image have to be non-premultiplied? Can I make a premultiplied image non-premultiplied using ImageMagick?

Update:
Ok, here are the images as TGA for download:

http://acatysmoof.com/posting/problems/imagemagick/premultiplication/bg.tga http://acatysmoof.com/posting/problems/imagemagick/premultiplication/whitecloud.tga http://acatysmoof.com/posting/problems/imagemagick/premultiplication/aftereffects.tga http://acatysmoof.com/posting/problems/imagemagick/premultiplication/imagemagick.tga

and in the same order as jpgs to view in your browser:

bg.jpg whitecloud.jpg aftereffects.jpg imagemagick.jpg

I tried all the modes provided, but none of them create the same result as After Effects.


Solution

  • The regular alpha blending operation (the Duff-Porter Over operator) does this:

    output.rgb = src.rgb * src.a + (1-src.a) * dst.rgb
    

    When the alpha is premultiplied, it just means that the color of the source is already src.rgb * src.a, so you only need to add (1-src.a) * dst.rgb.

    That's very quick in a shader. But in ImageMagick seems to get confusing because there doesn't seem to be a direct operator that does that.

    However, you can compute it if you break it down in several steps:

    # extract alpha channel from cloud
    convert whitecloud.tga -auto-orient -alpha extract -colorspace gray alpha.png
    # invert alpha channel
    convert alpha.jpg -negate alpha-inv.png
    # (1-cloud.a) * bg.rgb
    composite -compose Multiply alpha-inv.png bg.tga bg-pre.png
    # remove alpha channel to obtain cloud.rgb
    convert whitecloud.tga -auto-orient -alpha off whitecloud-rgb.png
    # cloud.rgb * cloud.a + (1-cloud.a) * bg.rgb
    composite -compose plus whitecloud-rgb.png bg-pre.png output.png
    

    Here's the output:

    This is the output

    For reference, here are a couple of the intermediate images,

    The alpha channel of the cloud

    Background multiplied with the inverse alpha of the cloud

    The advantage of splitting it in several steps is that it's easier to debug, in case your image has the wrong alpha channel or something.