3

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.

whereisalext
  • 680
  • 6
  • 12

5 Answers5

1

It would be easier if you showed your images, but try adding -compose lighten before -composite in your command, like this:

convert a.tga b.tga -compose lighten -composite out.tga

Basically that will make ImageMagick choose the lighter pixel of the two images at every point.

If that doesn't work, try other blending modes

for b in $(identify -list compose); do 
   convert -label "$b" bg.tga whitecloud.tga -compose $b -composite miff:- 
done | montage - -tile 5x out.png

enter image description here

I am kind of thinking Atop, Dissolve, SrcAtop and SrcOver might be your friends but have a look full-size and see what floats your boat. That would be

convert a.tga b.tga -compose Atop -composite out.tga
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • 1
    No, but I really appreciate the effort. Blend modes don't have anything to do with premultiplication. The RGB is not correct until the premultiplication takes place, and no blend mode is going to fix that. I did some research and both Imagemagick and Graphicsmagick do not support premultiplied alpha. That's really aggravating since most professional 2D and 3D software produces premultiplied images by default. All professional compositing packages also assume premultiplied alpha including After Effects, Fusion, Nuke, Harmony, etc. Imagemagick doesn't offer that. Why? I'll go ask on their lists. – whereisalext Mar 13 '15 at 05:17
  • Ok, thank you for the feedback. If there is a formula that can do/undo the premultiplication it may be possible to implement it in ImageMagick using the `-fx` operator, or a module, so if you find out more and care to add a note or link later it may be possible to work something out. – Mark Setchell Mar 13 '15 at 10:00
1

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

The alpha channel of the cloud

  • the background multiplied with the inverse of the alpha 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.

endavid
  • 1,781
  • 17
  • 42
1

I realise you asked for an imagemagick solution, but if other libraries are possible, libvips supports porter-duff composition with premultiplied alpha.

I made a PNG for your cloud image (this will look odd in a browser since the alpha is premultiplied):

enter image description here

Then ran:

$ vips composite2 bg.jpg white-cloud.png x.png over --premultiplied

To make:

enter image description here

Which I think matches aftereffects.

Here are the docs for the composite operator:

https://www.libvips.org/API/current/libvips-conversion.html#vips-composite

jcupitt
  • 10,213
  • 2
  • 23
  • 39
0

Here is an Imagemagick command that does what you want:

convert -gravity Center whitecloud.tga -fx "u/max(u.a, 1/255)" bg.tga +swap -composite -fx "u*u.a" comp.tga

What's happening here?

  1. -fx command #1: Convert whitecloud.tga from premultiplied alpha to "normal". The max() operator is a special case to avoid dividing by zero.
  2. +swap command: Make bg.tga the first image and the revised whitecloud.tga the second.
  3. -composite these two regular, non-premultiplied images.
  4. -fx command #2: take the result, and return to a premultiplied alpha format.

This gives exactly the same result as After Effects.

Note that, as I wrote it, it only works for an opaque bg.tga. You'd need to do some extra work to handle a transparent background image.

David Pritchard
  • 300
  • 3
  • 5
  • I tried this but it produces a gray cloud with black backgroud. The `bg.tga` is opaque so I'm not sure if I'm missing something here... – endavid Mar 28 '23 at 16:58
-1

If you want to duplicate the After Effects result, then I believe what you want to do in ImageMagick is the following -- composite the background image with a white image using the cloud as a mask:

convert bg.tga \( -clone 0 -fill white -colorize 100 \) whitecloud.tga -compose over -composite cloud_blue.tga

enter image description here

I have posted a JPG result, but my .tga result is the same.

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • This result is not correct. If you see the result from AfterEffects posted in the question, you can see that the cloud appears slightly greyer than yours. What you described is not what they want. I described it mathematically in my answer. – endavid Mar 28 '23 at 16:55