C# - GDI+编程教程

更新时间:2023-10-08 19:45:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

C#图形图像编程基础

本次课程主要介绍使用C#进行图形图像编程基础,其中包括GDI+绘图基础、C#图像处理基础以及简单的图像处理技术。

1 GDI+绘图基础

编写图形程序时需要使用GDI(Graphics Device Interface,图形设备接口),从程序设计的角度看,GDI包括两部分:一部分是GDI对象,另一部分是GDI函数。GDI对象定义了GDI函数使用的工具和环境变量,而GDI函数使用GDI对象绘制各种图形,在C#中,进行图形程序编写时用到的是GDI+(Graphice Device Interface Plus图形设备接口)版本,GDI+是GDI的进一步扩展,它使我们编程更加方便。

1.1 GDI+概述

GDI+是微软在Windows 2000以后操作系统中提供的新的图形设备接口,其通过一套部署为托管代码的类来展现,这套类被称为GDI+的“托管类接口”,GDI+主要提供了以下三类服务:

(1) 二维矢量图形:GDI+提供了存储图形基元自身信息的类(或结构体)、存储图形基元绘制方式信息的类以及实际进行绘制的类。

(2) 图像处理:大多数图片都难以划定为直线和曲线的集合,无法使用二维矢量图形方式进行处理。因此,GDI+为我们提供了Bitmap、Image等类,它们可用于显示、操作和保存BMP、JPG、GIF等图像格式。

(3) 文字显示:GDI+支持使用各种字体、字号和样式来显示文本。 我们要进行图形编程,就必须先讲解Graphics类,同时我们还必须掌握Pen、Brush和Rectangle这几种类。

GDI+比GDI优越主要表现在两个方面:第(一)GDI+通过提供新功能(例如:渐变画笔和alpha混合)扩展了GDI的功能;第(二)修订了编程模型,使图形编程更加简易灵活。

1.2 Graphics类

Graphics类封装一个GDI+绘图图面,提供将对象绘制到显示设备的方法,Graphics与特定的设备上下文关联。画图方法都被包括在Graphics类中,在画任何对象(例如:

Circle,Rectangle)时,我们首先要创建一个Graphics类实例,这个实例相当于建立了一块画布,有了画布才可以用各种画图方法进行绘图。

绘图程序的设计过程一般分为两个步骤:(一)创建Graphics对象;(二)使用Graphics对象的方法绘图、显示文本或处理图像。

通常我们使用下述三种方法来创建一个Graphics对象。 方法一、利用控件或窗体的Paint事件中的PainEventArgs

在窗体或控件的Paint事件中接收对图形对象的引用,作为PaintEventArgs

(PaintEventArgs指定绘制控件所用的Graphics)的一部分,在为控件创建绘制代码时,通常会使用此方法来获取对图形对象的引用。 例如:

//窗体的Paint事件的响应方法

private void form1_Paint(object sender, PaintEventArgs e) {

Graphics g = e.Graphics; }

也可以直接重载控件或窗体的OnPaint方法,具体代码如下所示:

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics; }

Paint事件在重绘控件时发生。

方法二、调用某控件或窗体的CreateGraphics方法

调用某控件或窗体的CreateGraphics方法以获取对Graphics对象的引用,该对象表示该控件或窗体的绘图图面。如果想在已存在的窗体或控件上绘图,通常会使用此方法。

例如:

Graphics g = this.CreateGraphics();

方法三、调用Graphics类的FromImage静态方法

由从Image继承的任何对象创建Graphics对象。在需要更改已存在的图像时,通常会使用此方法。

例如:

//名为“g1.jpg”的图片位于当前路径下

Image img = Image.FromFile(\);//建立Image对象 Graphics g = Graphics.FromImage(img);//创建Graphics对象

1.Graphics类的方法成员

有了一个Graphics的对象引用后,就可以利用该对象的成员进行各种各样图形的绘制,表7.1列出了Graphics类的常用方法成员。

表7.1 Graphics类常用方法

名称 说明 DrawArc DrawBezier DrawBeziers DrawClosedCurve DrawCurve DrawEllipse DrawImage DrawLine DrawPath DrawPie DrawPolygon DrawRectangle DrawString FillEllipse FillPath FillPie FillPolygon FillRectangle FillRectangles FillRegion 画弧。 画立体的贝尔塞曲线。 画连续立体的贝尔塞曲线。 画闭合曲线。 画曲线。 画椭圆。 画图像。 画线。 通过路径画线和曲线。 画饼形。 画多边形。 画矩形。 绘制文字。 填充椭圆。 填充路径。 填充饼图。 填充多边形。 填充矩形。 填充矩形组。 填充区域。 在.NET中,GDI+的所有绘图功能都包括在System、System.Drawing、System.Drawing.Imaging、System.Drawing.Darwing2D和System.Drawing.Text等命名空间中,因此在开始用GDI+类之前,需要先引用相应的命名空间。

2.引用命名空间

在C#应用程序中使用using命令已用给定的命名空间或类,下面是一个C#应用程序引用命名空间的例子:

using System;

using System.Collections.Generic; using System.Data;

using System.ComponentModel; using System.Drawing;

using System.Drawing.Drawing2D; using System.Drawing.Imaging;

1.3 常用画图对象

在创建了Graphics对象后,就可以用它开始绘图了,可以画线、填充图形、显示

文本等等,其中主要用到的对象还有:

? Pen:用来用patterns、colors或者bitmaps进行填充。 ? Color:用来画线和多边形,包括矩形、圆和饼形。 ? Font:用来给文字设置字体格式。 ? Brush:用来描述颜色。

? Rectangle:矩形结构通常用来在窗体上画矩形。 ? Point:描述一对有序的x,y两个坐标值。

1.Pen类

Pen用来绘制指定宽度和样式的直线。使用DashStyle属性绘制几种虚线,可以使用各种填充样式(包括纯色和纹理)来填充Pen绘制的直线,填充模式取决于画笔或用作填充对象的纹理。

使用画笔时,需要先实例化一个画笔对象,主要有以下几种方法。 用指定的颜色实例化一只画笔的方法如下:

public Pen(Color);

用指定的画刷实例化一只画笔的方法如下:

public Pen(Brush);

用指定的画刷和宽度实例化一只画笔的方法如下:

public Pen(Brush, float);

用指定的颜色和宽度实例化一只画笔的方法如下:

public Pen(Color, float);

实例化画笔的语句格式如下:

Pen pn=new Pen(Color.Blue);

或者Pen pn=new Pen(Color.Blue,100);

Pen常用的属性有以下几个,如表7.2所示:

表7.2 Pen常用属性

名称 Alignment Brush Color Width 2.Color结构

说明 获得或者设置画笔的对齐方式。 获得或者设置画笔的属性。 获得或者设置画笔的颜色。 获得或者设置画笔的宽度。 在自然界中,颜色大都由透明度(A)和三基色(R,G,B)所组成。在GDI+中,通过Color结构封装对颜色的定义,Color结构中,除了提供(A,R,G,B)以外,还提供许多系统定义的颜色,如Pink(粉颜色),另外,还提供许多静态成员,用于对颜色进行操作。Color结构的基本属性如表7.3所示。

表7.3 颜色的基本属性

名称 说明 A B G R Name 获取此Color结构的alpha分量值,取值(0~255)。 获取此Color结构的蓝色分量值,取值(0~255)。 获取此Color结构的绿色分量值,取值(0~255)。 获取此Color结构的红色分量值,取值(0~255)。 获取此Color结构的名称,这将返回用户定义的颜色的名称或已知颜色的名称(如果该颜色是从某个名称创建的),对于自定义的颜色,将返回RGB值。 表7.4 颜色的基本方法

Color结构的基本(静态)方法如表7.4所示

名称 FromArgb 说明 从四个8位ARGB分量(alpha、红色、绿色和蓝色)值创建Color结构。 从预定义颜色的指定名称创建一个Color结构。 FromKnowColor 从指定的预定义颜色创建一个Color结构。 FromName Color结构变量可以通过已有颜色构造,也可以通过RGB建立,例如: Color clr1 = Color.FromArgb(122,25,255);

Color clr2 = Color.FromKnowColor(KnowColor.Brown);//KnownColor为枚举类型 Color clr3 = Color.FromName(\

在图像处理中一般需要获取或设置像素的颜色值,获取一幅图像的某个像素颜色值的具体步骤如下:

(1)定义Bitmap Bitmap myBitmap = new Bitmap(\

(2)定义一个颜色变量把在指定位置所取得的像素值存入颜色变量中 Color c = new Color();

c = myBitmap.GetPixel(10,10);//获取此Bitmap中指定像素的颜色。

(3)将颜色值分解出单色分量值

int r,g,b; r= c.R; g=c.G; b=c.B;

3.Font类

Font类定义特定文本格式,包括字体、字号和字形属性。Font类的常用构造函数是public Font(string 字体名,float 字号,FontStyle 字形),其中字号和字体为可选项和public Font(string 字体名,float 字号),其中“字体名”为Font的FontFamily的字符串表示形式。下面是定义一个Font对象的例子代码:

FontFamily fontFamily = new FontFamily(\

Font font = new Font(fontFamily,16,FontStyle.Regular,GraphicsUnit.Pixel);

字体常用属性如表7.5所示。

表7.5 字体的常用属性

名称 Bold FontFamily Height Italic Name Size SizeInPoints Strikeout Style Underline Unit 4.Brush类

说明 是否为粗体。 字体成员。 字体高。 是否为斜体。 字体名称。 字体尺寸。 获取此 Font对象的字号,以磅为单位。 是否有删除线。 字体类型。 是否有下划线。 字体尺寸单位。 Brush类是一个抽象的基类,因此它不能被实例化,我们总是用它的派生类进行实例化一个画刷对象,当我们对图形内部进行填充操作时就会用到画刷,关于画刷在7.1.5中有详细讲解。

5.Rectangle结构

存储一组整数,共四个,表示一个矩形的位置和大小。矩形结构通常用来在窗体上画矩形,除了利用它的构造函数构造矩形对象外,还可以使用Rectangle结构的属性成员,其属性成员如表7.6所示。

表7.6 Rectangle结构属性

名称 Bottom Height IsEmpty Left Location Right Size Top Width X Y 说明 底端坐标 矩形高 测试矩形宽和高是否为0 矩形左边坐标 矩形的位置 矩形右边坐标 矩形尺寸. 矩形顶端坐标 矩形宽 矩形左上角顶点X坐标 矩形左上角顶点Y坐标 Retangle结构的构造函数有以下两个:

//用指定的位置和大小初始化Rectangle类的新实例。

public Retangle(Point,Size);//Size结构存储一个有序整数对,通常为矩形的宽度和高度。

public Rectangle(int,int,int,int);

6.Point结构

用指定坐标初始化Point类的新实例。这个结构很像C++中的Point结构,它描述了一对有序的x,y两个坐标值,其构造函数为:public Point(int x,int y);其中x为该点的水平位置;y为该点的水垂直位置。下面是构造Point对象的例子代码:

Point pt1=new Point(30,30); Point pt2=new Point(110,100);

71.4 基本图形绘制举例

1.画一个矩形

【例1】建立一个项目,在窗体上画一个矩形,通过直接在Form1类中重载OnPaint函数的方法来实现。

图1 画一个矩形

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics ;

Rectangle rect = new Rectangle(50, 30, 100, 100);

LinearGradientBrush lBrush = new LinearGradientBrush(rect, Color.Red,Color.Yellow,LinearGradientMode.BackwardDiagonal); g.FillRectangle(lBrush, rect);

}

运行结果如图1所示。 2.画一个弧

【例2】画一个弧形。 弧形函数格式如下:

public void DrawArc(Pen pen,Rectangle rect,Float startArgle,Float sweepAngle);

直接在Form1类中重载OnPaint函数

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics ; Pen pn = new Pen( Color.Blue);

Rectangle rect = new Rectangle(50, 50, 200,100); g.DrawArc(pn,rect,12,84); }

运行结果如图2所示。

图2 画一个弧

3.画线

【例3】画一条线。

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics ; Pen pn = new Pen(Color.Blue);

Point pt1 = new Point(30,30); Point pt2 = new Point(110,100); g.DrawLine(pn,pt1,pt2); }

运行结果如图3所示。

图3画一条线

4.画椭圆

【例4】画一个椭圆。

图4画一个椭圆

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics ;

Pen pn = new Pen( Color.Blue, 100 );

Rectangle rect = new Rectangle(50, 50, 200, 100); g.DrawEllipse( pn, rect ); }

运行结果如图4所示。 5.输出文本 【例5】输出文本。

protected override void OnPaint(PaintEventArgs e) {

Font fnt = new Font(\Graphics g = e.Graphics;

g.DrawString(\}

运行结果如图5所示。

图5 输出文本

6.填充路径 【例6】填充路径。

protected override void OnPaint(PaintEventArgs e) {

Graphics g = e.Graphics;

{

c = b.GetPixel(i,j); rr = c.R; gg = c.G; bb = c.B;

cc = (int)((rr + gg + bb) / 3); if (cc < 0) cc = 0;

if (cc > 255) cc = 255;

//用FromArgb把整型转换成颜色值

Color c1 = Color.FromArgb(cc, cc, cc); b1.SetPixel(i,j,c1);

}

pictureBox2.Refresh();//刷新

pictureBox2.Image = b1;//图片赋给图片框2 } }

(3)运行程序,程序运行结果如图24所示。

图24 灰度图像

3.灰度图像处理

【例12】改善对比度。

算法说明:本例根据特定的输入输出灰度转换关系,增强了图像灰度,处理后图像的中等灰度值增大,图像变亮。

注意:本例中描述对比度改善的输入、输出灰度值对应关系的程序段为:

lev= 80; wid =100;

for (x=0;x<256;x+=1) {

lut[x]=255; }

for (x=lev;x<(lev+wid);x++) {

dm =((double)(x-lev)/(double)wid)*255f; lut [x] =(int)(dm); }

(1)在窗体上添加一个“对比度”命令按钮。 (2)双击“对比度”命令按钮,编辑代码如下:

private void button5_Click(object sender, EventArgs e) {

Color c = new Color();

Bitmap box1 = new Bitmap(pictureBox1.Image); Bitmap box2 = new Bitmap(pictureBox1.Image); int rr, x, m, lev, wid; int[] lut = new int[256];

int [,,]pic=new int[600,600,3]; double dm; lev = 80; wid = 100;

for (x = 0; x < 256; x += 1) {

lut[x] = 255; }

for (x = lev; x < (lev + wid); x++) {

dm = ((double)(x - lev) / (double)wid) * 255f; lut[x] = (int)dm; }

for (int i = 0; i < pictureBox1.Image.Width - 1; i++) {

for (int j = 0; j < pictureBox1.Image.Height; j++) {

c = box1.GetPixel(i, j); pic[i, j, 0] = c.R; pic[i, j, 1] = c.G; pic[i, j, 2] = c.B; } }

for (int i = 0; i < pictureBox1.Image.Width - 1; i++) {

for (int j = 0; j < pictureBox1.Image.Height; j++) {

m = pic[i, j, 0]; rr=lut[m];

Color c1 = Color.FromArgb(rr, rr, rr); box2.SetPixel(i,j,c1); }

pictureBox2.Refresh(); pictureBox2.Image = box2; } }

(3)运行程序,运行结果如图25所示。

图25 改善对比度

SetPropertyItem 将指定的属性项设置为指定的值。 SetResolution 设置此Bitmap的分辨率。 Bitmap类有多种构造函数,因此可以通过多种形式建立Bitmap对象,例如: 从指定的现有图像建立Bitmap对象

Bitmap box1 =new Bitmap(pictureBox1.Image);

从指定的图像文件建立Bitmap对象,其中“C:\\MyImages\\TestImage.bmp”已存在的图像文件

Bitmap box2 =new Bitmap(\C:\\\\MyImages\\\\TestImage.bmp\);

从现有的Bitmap对象建立新的Bitmap对象

Bitmap box3 = new Bitmap(box1);

2.2 图像的输入和保存

1.图像的输入

在窗体或图形框内输入图像有两种方式:(一)在窗体设计时使用图形框对象的Image属性输入;(二)在程序中通过打开文件对话框输入。 方法(一)、窗体设计时使用图形框对象的Image属性输入 窗体设计时使用对象的Image属性输入图像的操作如下: (1)在窗体上,建立一个图形框对象(pictureBox1),选择图形框对象属性中的Image属性,如图12所示。

(2)单击Image属性右侧的【?】,弹出一个“选择资源”窗口,在该窗口中选择“本地资源”,单击【导入(M)...】将弹出一个“打开”对话框,如图13所示。

图12 Image属性

图13“打开”对话框

(3)选择图像文件后,单击【打开】按钮。 方法(二)、使用“打开文件”对话框输入图像

在窗体上添加一个命令按钮(button1)和一个图形框对象(pictureBox1),双击命令按钮,在响应方法中输入如下代码:

private void button1_Click(object sender, EventArgs e)

{

OpenFileDialog ofdlg = new OpenFileDialog(); ofdlg.Filter = \ if (ofdlg.ShowDialog() == DialogResult.OK) {

Bitmap image = new Bitmap(ofdlg.FileName); pictureBox1.Image = image; } }

执行该程序时,使用“打开文件”对话框,选择图像文件,该图像将会被打开,并显示在pictureBox1图像框中。

【例7】图像输入。

采用方法(二)来实现图像的输入。 设计步骤如下:

(1)建立如图14所示的项目界面,在窗体上加入【打开图像】命令按钮和一个PictureBox控件。

(2)双击【打开图像】命令按钮,编辑按钮的单击事件响应函数,其代码同方法(二)中所写代码,在此不再重复。

图14 图像输入

(3)运行后单击【打开图像】按钮,弹出一个“打开文件”对话框,选择图象文件名,运行结果如图15所示。

图15 运行结果

2.图像的保存

保存图像的步骤如下:

(1)当使用按钮和保存对话框保存文件时,加入保存按钮和PictureBox控件,窗体设计如图16所示。

(2)保存命令钮的单击事件的响应函数代码如下:

private void button2_Click(object sender, EventArgs e) {

string str;

Bitmap box1 = new Bitmap(pictureBox1.Image); SaveFileDialog sfdlg = new SaveFileDialog();

sfdlg.Filter = \文件(*.BMP)|*.BMP|All File(*.*)|*.*\ sfdlg.ShowDialog(); str = sfdlg.FileName; box1.Save(str); }

执行该过程时,将打开“另存为”对话框,如图17所示。

图16 保存图像

图17 “另存为”对话框

选择图像文件的保存路径。 3.图像格式的转换

使用Bitmap对象的Save方法,可以把打开的图像保存为不同的文件格式,从而实现图像格式的转换。在上述例子中添加一个命令按钮,双击该命令按钮,编辑其相应代码如下:

private void button3_Click(object sender, EventArgs e)

(3)双击【复制与粘贴】命令按钮,输入如下代码,将图像复制到第二个图片框中。

private void button2_Click(object sender, EventArgs e)

{

//使用枚举访问方法

axPictureClip1.Picture = pictureBox1.Image; axPictureClip1.Cols = 6;//将图片分成6列 axPictureClip1.Rows = 3;//将图片分成3行 try {

pictureBox2.Image = axPictureClip1.get_GraphicCell(0);//取出第一个图像块 }

catch (Exception ex) {

MessageBox.Show(ex.ToString()); }

}

(4)运行程序,单击【打开】命令按钮,选择一个图像文件打开,如图21所示,然后单击【复制与粘贴】命令按钮,运行结果如图22所示。

图21 打开图片后效果

(5)使用随机访问方法。

也可以使用随机访问方法,只需将上述例子中的【复制与粘贴】命令按钮的响应方法改为如下代码即可:

private void button2_Click(object sender, EventArgs e)

{

//使用随机访问方法

axPictureClip1.Picture = pictureBox1.Image;

axPictureClip1.ClipX = 15; axPictureClip1.ClipY = 15; axPictureClip1.ClipHeight = 50; axPictureClip1.ClipWidth = 50;

pictureBox2.Image = axPictureClip1.Clip;//

}

图22 粘贴后效果

注意:如果没有PICCLP32.OCX控件,需要自行下载或复制PICCLP32.OCX到本机,并通过注册程序REGSVR32注册该组件。例如,如果该文件在C:\\WINDOWS\\system32\\路径下,可以通过如下命令行语句实现注册:REGSVR32 C:\\WINDOWS\\system32\\PICCLP32.OCX

2.4 彩色图像处理

1.图像的分辨率

所谓分辨率就是指画面的解析度,由多少像素构成,数值越大,图像也就越清晰。我们通常所看到的分辨率都以乘法形式表现的,例如800*600,其中“800”表示屏幕上水平方向显示的点数,“600”表示垂直方向的点数。图像分辨率越大,越能表现更丰富的细节。图像的分辨率决定了图像与原物的逼进

程度,对同一大小的图像,其像素数越多,即将图像分割的越细,图像越清晰,称之为分辨率高,反之为分辨率低,分辨率的高低取决于采样操作。例如,对于一幅256*256分辨率的图像,采用变换的方法可以实现不同分辨率显示。

【例10】将256*256分辨率的图像变换为64*64分辨率。

算法说明:将256*256分辨率的图像变换为64*64分辨率方法是将源图像分成4*4的子图像块,然后将该4*4子图像块的所有像素的颜色按F(i,j)的颜色值进行设定,达到降低分辨率的目的。

建立一个如图23所示界面的项目,【分辨率】命令按钮的响应方法的代码设计如下: private void button3_Click(object sender, EventArgs e)

{

Color c = new Color();

//把图片框中的图片给一个Bitmap类型

Bitmap box1 = new Bitmap(pictureBox1.Image); Bitmap box2 = new Bitmap(pictureBox1.Image); int r, g, b, size, k1, k2, xres, yres, i, j; xres = pictureBox1.Image.Width; yres = pictureBox1.Image.Height; size = 4;

for (i = 0; i <= xres - 1; i += size) {

for (j = 0; j <= yres - 1; j += size) {

c = box1.GetPixel(i, j); r = c.R; g = c.G; b = c.B;

//用FromArgb把整型转换成颜色值

Color cc = Color.FromArgb(r, g, b); for (k1 = 0; k1 <= size - 1; k1++) {

for (k2 = 0; k2 <= size - 1; k2++) {

if (i + k1 < pictureBox1.Image.Width) box2.SetPixel(i + k1, j + k2, cc); } } } }

pictureBox2.Refresh();//刷新

pictureBox2.Image = box2;//图片赋到图片框中 }

输入图像分辨率为256*256像素,转换为64*64分辨率图像如图23所示。

图23 分辨率

2.彩色图像变换灰度图像

(1)彩色位图图像的颜色 图像像素的颜色是由三种基本色颜色,即红(R)、绿(G)、蓝(B)有机组合而成的,称为三基色。每种基色可取0~255的值,因此由三基色可组合成(256*256*256)1677万种颜色,每种颜色都有其对应的R、G、B值。例如,常见的7种颜色及其对应的R、G、B值如表11所示。

表11 常见的7种颜色及其对应的R、G、B值

颜色名 红 蓝 绿 白 黄 黑 青 品红

R值 255 0 0 255 255 0 0 255 G值 0 0 255 255 255 0 255 0 B值 0 255 0 255 0 0 255 255 (2)彩色图像颜色值的获取 在使用C#系统处理彩色图像时,使用Bitmap类的GetPixel方法获取图像上指定像素的颜色值,格式为:

Color c = new Color(); c = box1.GetPixel(i,j);

其中,(i,j)为获得颜色的坐标位置。GetPixel方法取得指定位置的颜色值并返回

一个长整型的整数。例如,求图片框1中图像在位置(i,j)的像素颜色值c时,可写为: Color c=new Color();

c = box1.GetPixel(i,j);

(3)彩色位图颜色值分解

像素颜色值c是一个长整型的数值,占4个字节,最上位字节的值为“0”,其它3个下位字节依次为B、G、R,值为0~255。 从从值分解出R、G、B值可直接使用: Color c =new Color();

c= box1.GetPixel(i,j); r=c.R; g=c.G; b=c.B;

(4)图像像素颜色的设定

设置像素可使用SetPixel方法。用法如下:

Color c1=Color.FromArgb(rr,gg,bb); Box2.SetPixel(i+k1,j+k2,c1);

【例11】彩色图像生成灰度图像。

算法说明:将彩色图像像素的颜色值分解为三基色R、G、B,求其和的平均值,然后使用SetPixel方法以该平均值参数生成图像。

其相应的代码设计如下: c = b.GetPixel(i,j);

r = c.b; g = c.G; b = c.B;

cc = (int)((r+g+b)/3); if (cc<0)cc=0; f (cc>255)cc=255;

Color c1 = Color.FromArgb(cc,cc,cc); B1.SetPixel(i,j,c1);

(1)在上例中增加一个【灰度图像】命令按钮。 (2)双击该按钮,编辑其响应方法的代码如下: private void button4_Click(object sender, EventArgs e)

{

Color c = new Color();

//把图片框1中的图片给一个Bitmap类型

Bitmap b = new Bitmap(pictureBox1.Image); Bitmap b1 = new Bitmap(pictureBox1.Image); int rr, gg, bb, cc;

for (int i = 0; i < pictureBox1.Width; i++) {

for (int j = 0; j < pictureBox1.Height; j++)

本文来源:https://www.bwwdw.com/article/6uyf.html

Top