[Interest] The "Proper" Way to Mix/Cross-Fade Images

Josiah Bryan josiahbryan at gmail.com
Tue Mar 20 14:17:49 CET 2012

I may be crazy, or just aiming for something unrealistic. But here goes:

- I want to cross-fade two images over a background. (Simple, right?)

Well, not really. Forgot the "Cross-fading" part - lets just take one point
in time, a 50/50 opacity (e.g. the two images we're cross fading each is at
50% opacity.) What would that look like if you just did this
straight-forward? (Paint background, paint 1st image at .5 opac, paint 2nd
image at .5 opac)

Well, it would look like this:
http://www.jdbryanphotography.com/fullres/fadetest-bg-renderout.png (200px
by 200px PNG image)
(For those who don't want to click - the blue background with the word
"(bg)" on it is visible through the partial-opacity "B" behind the
partial-opacity "A")

This would be coded like:
    double opac = .5;
 // render this image now over the background and you get the above link's

But I don't think the background should show thru - if each image is
exactly 50% opac, in my (simple) mind, that should "add up to" 100% opacity
- This is what I want to see:
http://www.jdbryanphotography.com/fullres/output-goal.png (200px by 200px
PNG image)
(No clicky? Solid red background with partial-opacity A over partial
opacity B)

However, the "best" so far that I can come up with (without cheating) is
http://www.jdbryanphotography.com/fullres/output-bestsofar.png (200px by
200px PNG image)
(No clicky? 75% red bg with same partial-opacity letters.)

Here's the source of the example (self-contained, 116 lines of cpp):
Using the following images as source:

(Basically, I render the image as above, then I create another image to use
as the alpha channel, extract the alpha channels of the first two images
(image1 and image2), then render them the same way (1.0-opac, draw, opac,
draw), then I set the alpha channel image as the alpha channel on the first
rendered image)

** The main problem I can't figure out **
My main.cpp example linked here would work perfectly for my problem, EXCEPT
that even when mixing the alpha chan properly, the resultant image is 25%
darker than it should be - e.g. the solid red areas in "-bestsofar.png" are
189 red instead of 255 red. Shouldn't 50% of red from fadetest-A.png at
pixel X,Y mixed with 50% red from fadetest-B.png at the same pixel X,Y be
100% red in the output image?

(Well, I can "force" it to render how I want - just render the first image
with 100% opacity - see the comment about "Want to cheat?" in the main.cpp.
But if I cheat, that wouldn't work for images that have different areas
with different opacities - say trying to crossfade between two words (100%
opacity) rendered on a 30% black background.)

** The other (side) problem **
This method is dog-slow - 4ms for me just to render and set the alpha
channel (not to mention the 4ms to render the initial mixed image.) And
thats with a 200x200 image - I'm talking about doing this with
1024x768px-sized images - which would (if I extrapolate correctly) be about
20-50ms a frame - ouch.

So it all boils down to this:
Is there any way to force QPainter (or, heck, just do it on a raw OpenGL
surface and skip QPainter/QImage all together) to blend things where 50%
opacity + 50% opacity = 100% opacity in the resultant image?

Or, as some might say, am I just waayyyy off base here? Perhaps the mere
mention of this idea is causing Porter and/or Duff to want to smack me with
a stick...I don't know. Any thoughts?

Anyway, thanks for your thoughts and feedback. Cheers!

Josiah Bryan
josiahbryan at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20120320/9abc7acf/attachment.html>

More information about the Interest mailing list