计算机对颜色的表示,有很多种方式。如RGB模式、HSB(HSV)模式、CMYK模式等。这里重点讲如何用C#语言,生成一个RGB模式的调色盘。
先看效果图:
在计算机中,一个像素点的颜色,由三种颜色构成:红色(R),蓝色(B)和绿色(G)构成。每种颜色的最大值为255,最亮,最小值为0,最暗。因此,构建一张这样的图片,重点就在于三种颜色如何进行混合。
因为有三种颜色,首先很容易想到,将一个圆,三等份,每一份表示一种颜色,其颜色值为255,这就构成了基本的调试盘。例如在-60°~60°这个区间内,所有像素的颜色值,R = 255, G =0, B =0。如下图所示:
有了这一个调色盘之后,就需要将各种颜色,向相邻的区域进行扩散。如何扩散,是调色盘绘制的关键。
颜色的扩散,有两个方向:
- 圆周扩散:从一个颜色的边缘,沿着圆周向相邻区域扩散;
- 径向扩散:从圆的中心点,向圆周扩散。
那么扩散的范围呢?通常的做法如下:
- 圆周的扩散范围是60°。例如红色,在60°~120°、-120°~-60°的区间内,圆周上各像素点的R值,从255按比例减少至0。在120°~180°、-180°~-120°区间内,圆周上各像素点的R值,均为0;
- 径向扩散的范围是120度。例如红色,在60°~180°、-180°~-60°的区间内,沿着半径的方向,各像素点的R值,从255按比例减少至圆周像素点的R值。
如下图所示:
有了这两条规则,就可以计算出每一个点的颜色值。
核心代码如下:
public Color GetColor(int x, int y,int radius)
{
// radius为圆的半径
// 已圆心为坐标原点,水平向右为起始向量
Vector o = new Vector(radius, 0);
// r,g,b为三个原色分量
byte r, g, b;
// 点(x,y)到圆心的距离
double distance = Math.Sqrt(Math.Pow(x - radius, 2) + Math.Pow(y - radius, 2));
// 距离大于半径,说明点在圆的外面,不用计算器颜色
if (distance > radius) return new Color() { A = 0 }
// 将(x,y)换算成已圆心为坐标原点的坐标,并计算向量(x1,y1)与起始向量的夹角
Vector v1 = new Vector(x - radius, radius - y);
double angel = Vector.AngleBetween(o, v1);
if (angel <= -60)
{
// 落在蓝色区间
r = CalculateSpread(distance, -angel - 60);
g = CalculateSpread(distance, 180 + angel);
b = 255;
}
else if (angel <= 60)
{
// 落在红色区间
r = 255;
g = CalculateSpread(distance, 60 - angel);
b = CalculateSpread(distance, 60 + angel);
}
else
{
// 落在绿色区间
r = CalculateSpread(distance, angel - 60);
g = 255;
b = CalculateSpread(distance, 180 - angel);
}
return new Color() { R = r, G = g, B = b, A = 255 };
}
// 计算某个颜色的分量。
// distance为点到圆心的距离;
// angel为点与圆心的连线,与颜色的边界之间的夹角
private byte CalculateSpread1(double distance, double angel, int radius)
{
// 计算圆周分量:如果两个向量的夹角大于60度,则圆周分量为0;否则,计算比例递减
double circum = angel > 60 ? 0 : circum = 255 - (angel / 60 * 255);
return (byte)(255 - distance / radius * (255 - circum));
}
关于控件的制作,下回讲解