简体   繁体   English

GDI alpha如何混合颜色?

[英]How does GDI alpha blend colors?

I simply need a function which takes two colors and returns the mixed version of them. 我只需要一个带两种颜色的函数并返回它们的混合版本。 It should mix them in the same way that GDI does. 它应该以与GDI相同的方式混合它们。

I figured that the alpha value you get when mixing two ARGB colors in GDI is calculated like this: 我想在GDI中混合两种ARGB颜色时得到的alpha值是这样计算的:

Private Function blend(alphaBelow As Single, alphaAbove As Single) As Single
    Return alphaBelow + (1.0 - alphaBelow) * alphaAbove
End Function

I also found this page where Microsoft says that the R, G and B values are calculated using this formula: 我还找到了这个页面 ,其中Microsoft表示使用以下公式计算R,G和B值:

displayColor = sourceColor × alpha / 255 + backgroundColor × (255 – alpha) / 255 displayColor = sourceColor×alpha / 255 + backgroundColor×(255 - alpha)/ 255

however, I can't get that to work: 但是,我无法让它工作:

Color1:          A=164, R=111, G=78, B=129
Color2:          A=241, R=152, G=22, B=48
Blended in GDI:  A=250, R=150, G=24, B=50

R:
150 = 152 * x / 255 + 111 * (255 - x) / 255
x = 9945/41 = 242.5609756097560975609756097561

G:
24 = 22 * x / 255 + 78 * (255 - x) / 255
x = 6885/28 = 245.89285714285714285714285714286

B:
50 = 48 * x / 255 + 129 * (255 - x) / 255
x = 6715/27 = 248.7037037037037037037037037037

As you can see, I get different alpha values for each of the R, G and B values. 如您所见,我为每个R,G和B值获得不同的alpha值。 How is this number calculated? 这个数字是如何计算的?

EDIT: 编辑:

Color1 and Color2 is just some random ARGB colors I want to mix together. Color1和Color2只是我想要混合在一起的一些随机ARGB颜色。 "Blended in GDI" is what you get if you draw them on top of eachother in a bitmap. 如果你在位图中将它们绘制在彼此之上,那么“混合在GDI中”就是你得到的。

The code which mixes the colors with GDI: 将颜色与GDI混合的代码:

    Dim B As New Bitmap(Width, Height, Imaging.PixelFormat.Format32bppPArgb)
    Dim G = Graphics.FromImage(B)
    Dim w = B.Width - 1, h = B.Height - 1

    G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias

    Dim pth As New Drawing2D.GraphicsPath
    pth.AddRectangle(New Rectangle(0, 0, w, h))

    Dim c1 = RandomColor(), c2 = RandomColor()
    G.FillPath(New SolidBrush(c1), pth)
    G.FillPath(New SolidBrush(c2), pth)

    Dim resoult As Color = B.GetPixel(w / 2, h / 2)

After hours of searching I solved my problem. 经过几个小时的搜索,我解决了我的问题 I'm just gonna post it here in case anypony need it in the future. 我将在这里发布,以防万一将来需要它。

Private Function MixColors(c1 As Color, c2 As Color) As Color
    Dim c1a = c1.A / 255, c2a = c2.A / 255, alp = AlphaBlend(c1a, c2a)

    Dim a = alp * 255
    Dim r = ColorBlend(c1.R, c1a, c2.R, c2a, alp)
    Dim g = ColorBlend(c1.G, c1a, c2.G, c2a, alp)
    Dim b = ColorBlend(c1.B, c1a, c2.B, c2a, alp)

    Return Color.FromArgb(CInt(a), CInt(r), CInt(g), CInt(b))
End Function

Private Function ColorBlend(c1r%, c1a#, c2r%, c2a#, alp#) As Single
    Return (c2r * c2a + c1r * c1a * (1 - c2a)) / alp
End Function

Private Function AlphaBlend(alphaBelow!, alphaAbove!) As Double
    Return alphaBelow + (1.0 - alphaBelow) * alphaAbove
End Function

Please note that I developed this function by myself and did not get it from Microsoft or anything, so I cannot prove that it calculates mixing of colors in the same way that GDI does. 请注意,我自己开发了这个功能,并没有从微软或任何东西得到它,所以我无法证明它以与GDI相同的方式计算颜色的混合。 All tho I have not expirienced that the function missbehaves myself, I cannot guarantee that it will return the excact same resoult as GDI does, but it should be very very close. 所有这些我没有说明这个函数没有自己的功能,我不能保证它会像GDI那样返回精确的同样的反应,但它应该非常接近。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM