【发布时间】:2021-02-18 10:15:07
【问题描述】:
我希望能够混合两个或多个 Color 对象。假设我从一个半透明的红色开始:
var red = Color.FromArgb(140, 255, 0, 0);
然后我想在其中混合半透明的绿色:
var green = Color.FromArgb(140, 0, 255, 0);
我遇到的颜色混合代码 sn-ps 通常会在此处产生棕色阴影,但我真正想要的是一种效果,就像你要在上面绘制一种颜色时得到的效果一样另一个在(比如)Paint.Net,导致更多的深绿色:-
然后我想混合第三种颜色,比如半透明的蓝色:
var blue = Color.FromArgb(140, 0, 0, 255);
这一次,我想在这张图片的中心看到蓝绿色:
(同样,如果我尝试使用通常的代码 sn-ps,那么我通常会以灰色或棕色结束)。
顺便说一句,可能值得一提的是,以下代码几乎实现了我所追求的:
using (var bitmap = new Bitmap(300, 300))
{
using (var g = Graphics.FromImage(bitmap))
{
var c1 = Color.FromArgb(alpha: 128, red: 255, green: 0, blue: 0);
var c2 = Color.FromArgb(alpha: 200, red: 0, green: 255, blue: 0);
var c3 = Color.FromArgb(alpha: 100, red: 0, green: 0, blue: 255);
g.FillRectangle(new SolidBrush(c1), 100, 0, 100, 100);
g.FillRectangle(new SolidBrush(c2), 125, 75, 100, 100);
g.FillRectangle(new SolidBrush(c3), 75, 50, 100, 100);
}
}
我猜它的代码相当于我的 Paint.Net 步骤,在另一个上绘制一个半透明的彩色矩形。但是我希望能够计算出最终的混合颜色,并在一次调用g.FillRectangle() 时使用它,而不是调用该方法三次来达到混合效果。
最后,这是我之前提到的那种颜色混合代码 sn-p 的示例,当我将它们用于我的颜色时通常会产生棕色阴影:-
private Color Blend(Color c1, Color c2)
{
var aOut = c1.A + (c1.A * (255 - c1.A) / 255);
var rOut = (c1.R * c1.A + c2.R * c2.A * (255 - c1.A) / 255) / aOut;
var gOut = (c1.G * c1.A + c2.G * c2.A * (255 - c1.A) / 255) / aOut;
var bOut = (c1.B * c1.A + c2.B * c2.A * (255 - c1.A) / 255) / aOut;
return Color.FromArgb(aOut, rOut, gOut, bOut);
}
【问题讨论】:
-
您说的很对:gdi 绘图的 alpha 混合模式仅限于一种。要获得更多,比如说您需要编写一个或多个自己的例程的 Photoshop 图层混合模式集。数学可以在here 找到。我这样做是为了全套模式,然后是一些在 c# 中,也许我应该将它发布到 git 但 atm 我没有时间.. - Otoh,如果你想完全控制覆盖区域,你可能需要剖析数字并分别填写。
-
@TaW 非常感谢,我没有完全理解您的 C# 代码 sn-p 中的四个参数,但是通过一些试验和错误,我能够简化它并让它工作(以满足至少我的需要)。见下文。