Converting ARBG to RGB with alpha blending

12,924

Solution 1

It's called alpha blending.

In psuedocode, assuming the background color (blend) always has 255 alpha. Also assumes alpha is 0-255.

alpha=argb.alpha()
r = (alpha/255)*argb.r() + (1 - alpha/255)*blend.r()
g = (alpha/255)*argb.g() + (1 - alpha/255)*blend.g()
b = (alpha/255)*argb.b() + (1 - alpha/255)*blend.b()

note: you probably need to be a bit (more) careful about floating-point/int math and rounding issues, depending on language. Cast intermediates accordingly

Edited to add:

If you don't have a background color with an alpha of 255, the algebra gets alot more complicated. I've done it before and it's a fun exercise left to the reader (if you really need to know, ask another question :).

In other words, what color C blends into some background the same as blending A, then blending B. This is sort of like calculating A+B (which isn't the same as B+A).

Solution 2

I know this is an old thread, but I want to add this:

Public Shared Function AlphaBlend(ByVal ForeGround As Color, ByVal BackGround As Color) As Color
    If ForeGround.A = 0 Then Return BackGround
    If BackGround.A = 0 Then Return ForeGround
    If ForeGround.A = 255 Then Return ForeGround
    Dim Alpha As Integer = CInt(ForeGround.A) + 1
    Dim B As Integer = Alpha * ForeGround.B + (255 - Alpha) * BackGround.B >> 8
    Dim G As Integer = Alpha * ForeGround.G + (255 - Alpha) * BackGround.G >> 8
    Dim R As Integer = Alpha * ForeGround.R + (255 - Alpha) * BackGround.R >> 8
    Dim A As Integer = ForeGround.A

    If BackGround.A = 255 Then A = 255
    If A > 255 Then A = 255
    If R > 255 Then R = 255
    If G > 255 Then G = 255
    If B > 255 Then B = 255

    Return Color.FromArgb(Math.Abs(A), Math.Abs(R), Math.Abs(G), Math.Abs(B))
End Function

public static Color AlphaBlend(Color ForeGround, Color BackGround)
{
    if (ForeGround.A == 0)
        return BackGround;
    if (BackGround.A == 0)
        return ForeGround;
    if (ForeGround.A == 255)
        return ForeGround;

    int Alpha = Convert.ToInt32(ForeGround.A) + 1;
    int B = Alpha * ForeGround.B + (255 - Alpha) * BackGround.B >> 8;
    int G = Alpha * ForeGround.G + (255 - Alpha) * BackGround.G >> 8;
    int R = Alpha * ForeGround.R + (255 - Alpha) * BackGround.R >> 8;
    int A = ForeGround.A;

    if (BackGround.A == 255)
        A = 255;
    if (A > 255)
        A = 255;
    if (R > 255)
        R = 255;
    if (G > 255)
        G = 255;
    if (B > 255)
        B = 255;

    return Color.FromArgb(Math.Abs(A), Math.Abs(R), Math.Abs(G), Math.Abs(B));
}

Solution 3

if you don't need to know this pre-render, you could always use the win32 method of getpixel, I believe.

Note: typing on iPhone in the middle of Missouri with no inet access. Will look up real win32 example and see if there is a .net equivalent.

In case anyone cares, and doesn't want to use the (excellent) answer posted above, you can get the color value of a pixel in .Net via this link MSDN example

Share:
12,924

Related videos on Youtube

Bob
Author by

Bob

Updated on April 15, 2022

Comments

  • Bob
    Bob about 2 years

    Let's say that we have an ARGB color:

    Color argb = Color.FromARGB(127, 69, 12, 255); //Light Urple.
    

    When this is painted on top of an existing color, the colors will blend. So when it is blended with white, the resulting color is Color.FromARGB(255, 162, 133, 255);

    The solution should work like this:

    Color blend = Color.White; 
    Color argb = Color.FromARGB(127, 69, 12, 255); //Light Urple.      
    Color rgb = ToRGB(argb, blend); //Same as Color.FromARGB(255, 162, 133, 255);
    

    What is ToRGB's implementation?

    • Matt Dawdy
      Matt Dawdy over 6 years
      I just want to say that I find it awesome that "Light Urple" has survived 4 edits.