Assuming that you are in fact working with bitmaps, you'll likely find it easier to just let the library do this for you.
The System.Drawing.Graphics
class has a CompositingMode
property that can be set to either SourceCopy
(the default - overwrites the background colour) or SourceOver
(blends with the background color).
See MSDN: How to Use Compositing Mode to Control Alpha Blending for more detail.
If you just want the raw math, alpha blending is pretty simple. For an alpha value a between 0.0 and 1.0, the result should be:
(aOld * oldValue) + ((1 - aOld) * aNew * newValue)
Where oldValue
is the previous value before overlay, newValue
is what you want to overlay with, and aOld
and aNew
are the old and new alpha values respectively. You obviously need to do this calculation for the R, G, and B values separately.
See also: Alpha Compositing (wiki link) for a more thorough explanation.
Update: I think it should be easy to figure out how to adapt this to the code in the OP, but I guess not everybody's a math person.
I'm going to assume that the byte[]
is a repeating sequence of A, R, G, B values (so Length
would be a multiple of 4). If that's not the case, then you'll have to adapt this code to whatever storage format you're using.
bytes[] result = new bytes[first.Length];
for(i = 0; i < first.Length; i += 4)
{
byte a1 = first[i];
byte a2 = second[i];
byte r1 = first[i+1];
byte r2 = second[i+1];
byte g1 = first[i+2];
byte g2 = second[i+2];
byte b1 = first[i+3];
byte b2 = second[i+3];
byte a = a1 + (255 - a1) * a2 / 255;
byte r = r1 * a1 / 255 + r2 * (255 - a1) * a2 / 65025;
byte g = g1 * a1 / 255 + g2 * (255 - a1) * a2 / 65025;
byte b = b1 * a1 / 255 + b2 * (255 - a1) * a2 / 65025;
result[i] = a;
result[i+1] = r;
result[i+2] = g;
result[i+3] = b;
}