17.2 图形绘制5
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
17.2.6 颜色
通常情况下,我们所见的颜色都可以用红色、绿色、蓝色三种颜色按照不同比例混合而成,因此红绿蓝又称为三原色(对应英文R(red)、G(green)、B(blue))。目前RGB色彩、模式是工业界的颜色标准之一(还有CMYK等)。
图17-17 三原色
RGB色彩每种颜色都有0-255级亮度,其中 0 表示没有亮度,255 表示最大亮度。这样计算下来,RGB色彩总共能组合出约1678万种颜色,即256×256×256=16777216=2^24,也就是所说的24位色。计算机中又增加了透明度(Alpha)的概念,0 表示完全透明,255 表示完全不透明。这样计算下来,ARGB色彩总共能组合出约万种颜色,即256×256×256×256=4294967296=2^32,也就是所说的32位色。
C#使用Color结构表示一种 ARGB颜色(alpha、红色、绿色、蓝色)。通常可以使用以下几种方法来获取颜色:
1、使用FromArgb方法,例如:
Color myColor = Color.FromArgb(255, 0, 0);
这是常见的从指定的 8 位颜色值(红色、绿色和蓝色)创建 Color 结构,此方法中Alpha值默认为 255(完全不透明)。
2、使用预定义颜色的指定名称,例如:
Color myColor = Color.FromName("red");
其中名称是作为预定义颜色名称的字符串
3、直接使用已经定义的静态成员,例如:
Color myColor = Color.Red;
Color常用属性:
- A:获取alpha分量值。
- B:获取蓝色分量值。
- G:获取绿色分量值。
- R:获取红色分量值。
Color常用方法:
- FromArgb:创建 Color 结构。
- GetBrightness:获取“色调-饱和度-亮度”(HSB)的亮度值。
- GetSaturation:获取“色调-饱和度-亮度”(HSB)的饱和度值。
- ToArgb:获取32位ARGB值,它的字节顺序为 AARRGGBB。由AA、RR、GG 和 BB分别表示alpha分量值、红色分量值、绿色分量值和蓝色分量值。
【例 17.15】【项目:code17-015】制作一个调色板。
在窗体上放置4个PictureBox控件(其中三个以pic+颜色名称命名),3个HscrollBar控件(以hsb+颜色名称命名),3个label控件(以lbl+颜色名称命名),1个TextBox控件。
为了形象说明RGB颜色,红色、绿色、蓝色,每种颜色对应一个HscrollBar。注意为了使HscrollBar的值能够达到255,需要在代码中设置HscrollBar.Maximum = 255 + HscrollBar.LargeChange – 1。
窗体载入的时候,会在三个小图片框内显示红绿蓝三种颜色,当拖动任一滚动条时,picPalette的背景色跟随改变。
具体代码如下:
private void Form1_Load(object sender, EventArgs e)
{
hsbRed.Maximum = 255 + hsbRed.LargeChange - 1;
hsbRed.Value = 0;
hsbGreen.Maximum = 255 + hsbRed.LargeChange - 1;
hsbGreen.Value = 0;
hsbBlue.Maximum = 255 + hsbRed.LargeChange - 1;
hsbBlue.Value = 0;
picRed.BackColor = Color.Red;
picGreen.BackColor = Color.Green;
picBlue.BackColor = Color.Blue;
picPalette.BackColor = getColor();
}
//红色分量值变化
private void hsbRed_Scroll(object sender, ScrollEventArgs e)
{
lblRed.Text = hsbRed.Value.ToString();
picPalette.BackColor = getColor();
}
//绿色分量值变化
private void hsbGreen_Scroll(object sender, ScrollEventArgs e)
{
lblGreen.Text = hsbGreen.Value.ToString();
picPalette.BackColor = getColor();
}
//蓝色分量值变化
private void hsbBlue_Scroll(object sender, ScrollEventArgs e)
{
lblBlue.Text = hsbBlue.Value.ToString();
picPalette.BackColor = getColor();
}
private Color getColor()
{
//显示Web颜色
toWebColor();
//返回Color结构
return Color.FromArgb(hsbRed.Value, hsbGreen.Value, hsbBlue.Value);
}
//转换为Web颜色
private void toWebColor()
{
string hexRed = hsbRed.Value.ToString("X");
if( hexRed.Length == 1)
hexRed = "0" + hexRed;
string hexGreen = hsbGreen.Value.ToString("X");
if( hexGreen.Length == 1)
hexGreen = "0" + hexGreen;
string hexBlue = hsbBlue.Value.ToString("X");
if( hexBlue.Length == 1)
hexBlue = "0" + hexBlue;
txtWebColor.Text = "#" + hexRed + hexGreen + hexBlue;
}
运行结果如下图所示:
图17-18 颜色合成
【例 17.16】【项目:code17-016】图片上取色。
获得图片上某点的颜色,主要是用到Bitmap.GetPixel方法。
public Color GetPixel( int x, int y )
参数x,y 分别表示的是图片上某点的横轴坐标和纵轴坐标。
PictureBox.MouseClick事件的参数e是一个MouseEventArgs类,它的属性X、Y提供了鼠标事件时的x坐标和y坐标,正好为Bitmap.GetPixel提供了参数。
具体代码如下:
private void btnLoadImg_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "图片文件|*.jpg;*.png";
if (ofd.ShowDialog() != DialogResult.OK)
return;
string fileImage = ofd.FileName;
//载入图片
Bitmap imgScr = new Bitmap(fileImage);
Bitmap imgDest = new Bitmap(picColor.Width, picColor.Height);
Graphics g = Graphics.FromImage(imgDest);
g.DrawImage(imgScr, new Rectangle(0, 0, picColor.Width, picColor.Height), new Rectangle(0, 0, imgScr.Width, imgScr.Height), GraphicsUnit.Pixel);
picColor.Image = imgDest;
g.Dispose();
}
private void picColor_MouseClick(object sender, MouseEventArgs e)
{
//创建一个Bitmap对象
Bitmap pImage =new Bitmap(picColor.Image);
Color pColor;
//使用GetPixel()获得图片上鼠标点击处的颜色.
pColor = pImage.GetPixel(e.X, e.Y);
lblR.Text = pColor.R.ToString();
lblG.Text = pColor.G.ToString();
lblB.Text = pColor.B.ToString();
//在picPickColor显示颜色
picPickColor.BackColor = pColor;
lblx.Text = e.X.ToString();
lbly.Text = e.Y.ToString();
}
运行结果如下图所示:
图17-19 从图片上取色
注意:代码里面采用了Graphics.DrawImage()方法,程序中将原图缩放到了图片框大小,然后再图片框中显示出来,所以图片框中的鼠标点击获得的Point,对应图片的Point,所以取色是对的。如果将PictureBox的sizeMode属性设置为StretchImage,并使用以下语句载入图片:
picColor.Image = Image.FromFile(fileImage);
此时,使用Bitmap.GetPixel方法获得坐标位置的颜色是不正确的。
载入的图片被图片框缩放了,取色所用的坐标是PictureBox上的坐标,而不是源图片对应的坐标,获得的结果当然不正确。
图17-20 PictureBox坐标与图片坐标不符
学习更多vb.net知识,请参看vb.net 教程 目录
学习更多C#知识,请参看C#教程 目录