11

Possible Duplicate:
How to do alpha blend fast?

What is the fastest way to alpha blend 2 RGBA (Integer) colors?

As a note, the target color where to blend is always opaque, only the second color can have different levels of transparency.

I am trying to find the fastest way in C, taking into account that the final resulting color from the blend must end up with no transparency, fully opaque (alpha = 0xff)

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
PerracoLabs
  • 16,449
  • 15
  • 74
  • 127
  • Can you help us understand the difference between your question and that one? It appears that several of us are confused. – sblom Aug 18 '12 at 06:51
  • 3
    Not a duplicate. This asks about alpha blending in plain old `C`. The supposed question this duplicates asks a similar question, but in regards to `C++`. Two similar, but very different languages. – Braden Best Apr 03 '14 at 17:43

1 Answers1

16
int blend(unsigned char result[4], unsigned char fg[4], unsigned char bg[4])
{
    unsigned int alpha = fg[3] + 1;
    unsigned int inv_alpha = 256 - fg[3];
    result[0] = (unsigned char)((alpha * fg[0] + inv_alpha * bg[0]) >> 8);
    result[1] = (unsigned char)((alpha * fg[1] + inv_alpha * bg[1]) >> 8);
    result[2] = (unsigned char)((alpha * fg[2] + inv_alpha * bg[2]) >> 8);
    result[3] = 0xff;
}

I don't know how fast it is, but it's all integer. It works by turning alpha (and inv_alpha) into 8.8 fixed-point representations. Don't worry about the fact that alpha's min value is 1. In that case, fg[3] was 0, meaning the foreground is transparent. The blends will be 1*fg + 256*bg, which means that all the bits of fg will be shifted out of the result.

You could do it very fast, indeed, if you packed your RGBAs in 64 bit integers. You could then compute all three result colors in parallel with a single expression.

Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
  • 1
    Works simply perfect, and quite fast indeed. – PerracoLabs Aug 18 '12 at 10:24
  • 2
    Glad to hear it - not bad for untested code, while wasted at 2am? =] – Sniggerfardimungus Aug 18 '12 at 23:39
  • 1
    +1 I've been wracking my brain about how to get alpha blending to work for the better part of today. Your algorithm is the first I've tested that actually...well, works. – Braden Best Apr 03 '14 at 17:18
  • Is there a way to blend two semitransparent colors and get a non-opaque color from that using this algorithm? – Dev Sep 28 '19 at 15:52
  • @dev Two semi transparent colors can be blended in a similar way, but the final color would still be dependent upon a third color. Imagine that you have two panes of colored glass - one in front of the other. The color you see when you look is also dependent upon the color of whatever is behind them. The simplest way to do what you ask is to use the above formula to blend the background (bg) with the furthest of the two translucent colors (fg). This will give you a color (bg) that you then blend with the nearest of the translucent colors (fg), so the above method will work for what you want. – Sniggerfardimungus Sep 30 '19 at 03:12
  • @Sniggerfardimungus I'm not talking about overlaying anything over a solid background color. It can't be guaranteed that the background is 100% opaque. What if the background is transparent? What happens then? – Dev Sep 30 '19 at 04:41
  • @dev You can't have a final color that is dependent only upon translucent intermediates. Whatever the transparency of the intervening objects, the final color will _always_ incorporate the background color (multiplied by one minus the product of all the opacities of the intervening objects.) So even if you have two objects at 90% opacity, 1% of the final color will be whatever lies behind those two translucent objects. – Sniggerfardimungus Oct 01 '19 at 04:56
  • 2
    @Sniggerfardimungus Then how do image editors let you do that? Overlay RGBA+RGBA = RGB**A**? – Dev Oct 01 '19 at 08:11
  • 1
    @Dev The answer is the "A over B" operation of the Porter-Duff Composition. – DragonGamer Oct 30 '22 at 18:09