当前位置: 首页 > article >正文

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常用属性:

  1. A:获取alpha分量值。
  2. B:获取蓝色分量值。
  3. G:获取绿色分量值。
  4. R:获取红色分量值。

Color常用方法:

  1. FromArgb:创建 Color 结构。
  2. GetBrightness:获取“色调-饱和度-亮度”(HSB)的亮度值。
  3. GetSaturation:获取“色调-饱和度-亮度”(HSB)的饱和度值。
  4. 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#教程 目录


http://www.kler.cn/a/527337.html

相关文章:

  • 对比category_encoders库和sklearn库中的OrdinalEncoder
  • 【Proteus仿真】【51单片机】多功能计算器系统设计
  • 最近最少使用算法(LRU最近最少使用)缓存替换算法
  • 代码随想录算法训练营第三十八天-动态规划-完全背包-139.单词拆分
  • 当当网近30日热销图书的数据采集与可视化分析(scrapy+openpyxl+matplotlib)
  • 芯片AI深度实战:进阶篇之vim内verilog实时自定义检视
  • Streamlit入门
  • 04树 + 堆 + 优先队列 + 图(D1_树(D2_二叉树(BT)(D2_刷题练习)))
  • “星门计划对AI未来的意义——以及谁将掌控它”
  • Ethflow Round 1 (Codeforces Round 1001, Div. 1 + Div. 2)(A,B,C,E1)
  • hot100(4)
  • 对比DeepSeek、ChatGPT和Kimi的学术写作关键词提取能力
  • Baklib推动企业知识管理创新与效率提升的全面探讨
  • 计算机网络 性能指标相关
  • Python——基本数据类型——字符串类型
  • 代码随想录刷题day20|(哈希表篇)15.三数之和
  • 机器学习6-全连接神经网络2
  • 基于改进的强跟踪技术的扩展Consider Kalman滤波算法在无人机导航系统中的应用研究
  • 使用 Ollama 和 Kibana 在本地为 RAG 测试 DeepSeek R1
  • LeetCode 0541.反转字符串 II:模拟
  • C# 数组和列表的基本知识及 LINQ 查询
  • Spring Boot 基础开发:实现 RESTful API 开发
  • 【算法设计与分析】实验4:动态规划—0/1背包问题
  • Baklib赋能企业实现高效数字化内容管理提升竞争力
  • 【基于SprintBoot+Mybatis+Mysql】电脑商城项目之用户注册
  • 第05章 16 Implicit Function应用举例