How to mix two ARGB pixels?

Taken from the same Wikipedia article where you got the image:

C_o = C_a \alpha_a + C_b \alpha_b \left(1 - \alpha_a\right)

Translating to values which range from 0 to 255:

rOut = (rA * aA / 255) + (rB * aB * (255 - aA) / (255*255))
gOut = (gA * aA / 255) + (gB * aB * (255 - aA) / (255*255))
bOut = (bA * aA / 255) + (bB * aB * (255 - aA) / (255*255))
aOut = aA + (aB * (255 - aA) / 255)

The above is the wrong algorithm. This can be verified by substituting aA = 0. Then it turns out that if you are trying to blend color B with completely transparent color A, i.e. invisible, then logically the color B remains unchanged, but according to this formula it will be changed. The result of incorrect blending with gradient transparency. Therefore, the correct solution would be like this:

aOut = aA + (aB * (255 - aA) / 255)
rOut = (rA * aA + rB * aB * (255 - aA) / 255)/aOut 
gOut = (gA * aA + gB * aB * (255 - aA) / 255)/aOut 
bOut = (bA * aA + bB * aB * (255 - aA) / 255)/aOut 

The result of correct blending with gradient transparency.


It seems like this is what you want: http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending, but I'm a little confused by your notation since wikipedia says that argb values should range from 0.0 to 1.0. So I don't think this formula will give you FA=19. Can you clarify?

Edit: now that you took out the business about FA=19, I'm inclined to go with that formula.