C# GDI+绘图介绍
最近查阅网上资料,将GDI+的基本知识汇总如下:
一、基本的知识
GDI+:Graphics Device Interface Plus也就是图形设备接口,提供了各种丰富的图形图像处理功能;
在C#.NET中,使用GDI+处理二维(2D)的图形和图像,使用DirectX处理三维(3D)的图形图像,
图形图像处理用到的主要命名空间是System.Drawing,程序集:System.Drawing.d11:提供了对GDI+基本图形功能的访问,主要有Graphics类、Bitmap类、从Brush类继承的类、Font类、Icon类、Image类、Pen类、Color类等.
1.1Graphics类
俗称:画布,用于在其上面绘制相应的图像、图片、文字等内容...有以下三种创建方式
(1)利用窗体或控件的Paint事件的参数PaintEventArgs创建Graphics对象。
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
}
(2)使用窗体或控件的CreateGraphics方法
Graphics g=this.CreateGraphics();
Graphics g=this.button1.CreateGraphics();
(3)使用Image的派生类创建Graphics对象。使用Image的任何派生类均可以生成相应的Graphics对象,这种方法一般适用于在C#中对图像进行处理的场合。
Bitmap b=new Bitmap("Mybmp.bmp");
Graphics g=Graphics.FromImage(b);
1.2 Pen对象
Pen类的构造函数有四种,使用方法如下。
(1)创建某一颜色的Pen对象:public Pen(Color)
(2)创建某一刷子样式的Pen对象:public Pen(Brush)
(3)创建某—刷子样式并具有相应宽度的Pen对象:public Pen(Brush,float)
(4)创建某一颜色和相应宽度的Pen对象:public Pen(Color,float)
Pen对象的常用属性
(1)Alignment属性:用来获取或设置此Pen对象的对齐方式。
(2)Color属性:用来获取或设置此Pen对象的颜色。
(3)Width属性:用来获取或设置此Pen对象的宽度。
(4)DashStyle属性:用来获取或设置通过此Pen对象绘制的虚线的样式。
(5)DashCap属性:用来指定虚线两端风格,是一个DashCap枚举型的值。
(6)StartCap属性:用来获取或设置通过此Pen对象绘制的直线起点的帽样式。
(7)EndCap属性:用来获取或设置通过此Pen对象绘制的直线终点的帽样式。
(8)PenType属性:用来获取用此Pen对象绘制的直线的样式。
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics; //创建画板,这里的画板是由Form提供的.
Pen p = new Pen(Color.Blue, 2);//定义了一个蓝色,宽度为的画笔
g.DrawLine(p, 10, 10, 100, 100);//在画板上画直线,起始坐标为(10,10),终点坐标为(100,100)
g.DrawRectangle(p, 10, 10, 100, 100);//在画板上画矩形,起始坐标为(10,10),宽为,高为
g.DrawEllipse(p, 10, 10, 100, 100);//在画板上画椭圆,起始坐标为(10,10),外接矩形的宽为,高为
}
1.3Brush类的使用
作用:我们可以用画刷填充各种图形形状,如矩形、椭圆、扇形、多边形和封闭路径等,主要有几种不同类型的画刷:
SolidBrush:画刷最简单的形式,用纯色进行绘制
• HatchBrush:类似于 SolidBrush,但是可以利用该类从大量预设的图案中选择绘制时要使用的图案,而不是纯色
• TextureBrush:使用纹理(如图像)进行绘制
• LinearGradientBrush:使用沿渐变混合的两种颜色进行绘制
• PathGradientBrush :基于编程者定义的唯一路径,使用复杂的混合色渐变进行绘制
以下是一段实例的代码
Graphics g = this.CreateGraphics();
Rectangle rect = new Rectangle(10, 10, 50, 50);//定义矩形,参数为起点横纵坐标以及其长和宽 //单色填充
SolidBrush b1 = new SolidBrush(Color.Blue);//定义单色画刷
g.FillRectangle(b1, rect);//填充这个矩形 //字符串
g.DrawString("字符串", new Font("宋体", 10), b1, new PointF(90, 10)); //用图片填充
TextureBrush b2 = new TextureBrush(Image.FromFile(@"e:\picture\1.jpg"));
rect.Location = new Point(10, 70);//更改这个矩形的起点坐标
rect.Width = 200;//更改这个矩形的宽来
rect.Height = 200;//更改这个矩形的高
g.FillRectangle(b2, rect); //用渐变色填充
rect.Location = new Point(10, 290);
LinearGradientBrush b3 = new LinearGradientBrush(rect, Color.Yellow , Color.Black , LinearGradientMode.Horizontal);
g.FillRectangle(b3, rect);
二、其他知识点
2.1坐标轴的转化
在winform中的坐标轴和我们平时接触的平面直角坐标轴不同,winform中的坐标轴方向完全相反:窗体的左上角为原点(0,0),水平向左则X增大,垂直下向则Y增大

Graphics g = this.CreateGraphics(); //单色填充
//SolidBrush b1 = new SolidBrush(Color.Blue);//定义单色画刷
Pen p = new Pen(Color.Blue,1); //转变坐标轴角度
for (int i = 0; i < 90; i++)
{
g.RotateTransform(i);//每旋转一度就画一条线
g.DrawLine(p, 0, 0, 100, 0);
g.ResetTransform();//恢复坐标轴坐标
} //平移坐标轴
g.TranslateTransform(100, 100);
g.DrawLine(p, 0, 0, 100, 0);
g.ResetTransform(); //先平移到指定坐标,然后进行度旋转
g.TranslateTransform(100,200);
for (int i = 0; i < 8; i++)
{
g.RotateTransform(45);
g.DrawLine(p, 0, 0, 100, 0);
} g.Dispose();
2.2附加一段仿QQ截图形式的一种截图形式
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms; namespace Client
{
public partial class Catch : Form
{
public Catch()
{
InitializeComponent();
} #region 用户变量
private Point DownPoint = Point.Empty;//记录鼠标按下坐标,用来确定绘图起点
private bool CatchFinished = false;//用来表示是否截图完成
private bool CatchStart = false;//表示截图开始
private Bitmap originBmp;//用来保存原始图像
private Rectangle CatchRect;//用来保存截图的矩形
#endregion //窗体初始化操作
private void Catch_Load(object sender, EventArgs e)
{
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
this.UpdateStyles();
//以上两句是为了设置控件样式为双缓冲,这可以有效减少图片闪烁的问题,关于这个大家可以自己去搜索下
originBmp = new Bitmap(this.BackgroundImage);//BackgroundImage为全屏图片,我们另用变量来保存全屏图片
} //鼠标右键点击结束截图
private void Catch_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
this.DialogResult = DialogResult.OK;
this.Close();
}
} //鼠标左键按下时动作
private void Catch_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (!CatchStart)
{//如果捕捉没有开始
CatchStart = true;
DownPoint = new Point(e.X, e.Y);//保存鼠标按下坐标
}
}
} private void Catch_MouseMove(object sender, MouseEventArgs e)
{
if (CatchStart)
{//如果捕捉开始
Bitmap destBmp = (Bitmap)originBmp.Clone();//新建一个图片对象,并让它与原始图片相同
Point newPoint = new Point(DownPoint.X, DownPoint.Y);//获取鼠标的坐标
Graphics g = Graphics.FromImage(destBmp);//在刚才新建的图片上新建一个画板
Pen p = new Pen(Color.Blue,1);
int width = Math.Abs(e.X - DownPoint.X), height = Math.Abs(e.Y - DownPoint.Y);//获取矩形的长和宽
if (e.X < DownPoint.X)
{
newPoint.X = e.X;
}
if (e.Y < DownPoint.Y)
{
newPoint.Y = e.Y;
}
CatchRect = new Rectangle(newPoint,new Size(width,height));//保存矩形
g.DrawRectangle(p,CatchRect);//将矩形画在这个画板上
g.Dispose();//释放目前的这个画板
p.Dispose();
Graphics g1 = this.CreateGraphics();//重新新建一个Graphics类
//如果之前那个画板不释放,而直接g=this.CreateGraphics()这样的话无法释放掉第一次创建的g,因为只是把地址转到新的g了.如同string一样
g1 = this.CreateGraphics();//在整个全屏窗体上新建画板
g1.DrawImage(destBmp,new Point(0,0));//将刚才所画的图片画到这个窗体上
//这个也可以属于二次缓冲技术,如果直接将矩形画在窗体上,会造成图片抖动并且会有无数个矩形.
g1.Dispose();
destBmp.Dispose();//要及时释放,不然内存将会被大量消耗 }
} private void Catch_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (CatchStart)
{
CatchStart = false;
CatchFinished = true; }
}
} //鼠标双击事件,如果鼠标位于矩形内,则将矩形内的图片保存到剪贴板中
private void Catch_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left&&CatchFinished)
{
if (CatchRect.Contains(new Point(e.X, e.Y)))
{
Bitmap CatchedBmp = new Bitmap(CatchRect.Width, CatchRect.Height);//新建一个于矩形等大的空白图片
Graphics g = Graphics.FromImage(CatchedBmp);
g.DrawImage(originBmp, new Rectangle(0, 0, CatchRect.Width, CatchRect.Height), CatchRect, GraphicsUnit.Pixel);
//把orginBmp中的指定部分按照指定大小画在画板上
Clipboard.SetImage(CatchedBmp);//将图片保存到剪贴板
g.Dispose();
CatchFinished = false;
this.BackgroundImage = originBmp;
CatchedBmp.Dispose();
this.DialogResult = DialogResult.OK;
this.Close();
}
}
}
}
}
C.创建了Catch窗体后,我们在截图按钮(位于聊天窗体上)上加入以下事件: private void bCatch_Click(object sender, EventArgs e)
{ if (bCatch_HideCurrent.Checked)
{
this.Hide();//隐藏当前窗体
Thread.Sleep(50);//让线程睡眠一段时间,窗体消失需要一点时间
Catch CatchForm = new Catch();
Bitmap CatchBmp = new Bitmap(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height);//新建一个和屏幕大小相同的图片
Graphics g = Graphics.FromImage(CatchBmp);
g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.AllScreens[0].Bounds.Width, Screen.AllScreens[0].Bounds.Height));//保存全屏图片
CatchForm.BackgroundImage = CatchBmp;//将Catch窗体的背景设为全屏时的图片
if (CatchForm.ShowDialog() == DialogResult.OK)
{//如果Catch窗体结束,就将剪贴板中的图片放到信息发送框中
IDataObject iData = Clipboard.GetDataObject();
DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Bitmap);
if (iData.GetDataPresent(DataFormats.Bitmap))
{
richtextbox1.Paste(myFormat);
Clipboard.Clear();//清除剪贴板中的对象
}
this.Show();//重新显示窗体
}
} }
C# GDI+绘图介绍的更多相关文章
- MFC GDI绘图基础
一.关于GDI的基本概念 什么是GDI? Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Wind ...
- C#-gdi绘图,双缓冲绘图,Paint事件的触发
一. 画面闪烁问题与双缓冲技术 1.1 导致画面闪烁的关键原因分析: 1 绘制窗口由于大小位置状态改变进行重绘操作时 绘图窗口内容或大小每改变一次,都要调用Paint事件进行重绘操作,该操作会使画面 ...
- GDI+ 绘图闪烁解决方法
闲着没事,准备做一个类似于TeeChart的自定义控件,结果第一步的绘图就把我给难倒了,虽然早就知道GDI绘图的闪烁问题很坑,但是却没有想到如此之坑,折腾了两天,才找到解决方法. 首先在窗体加载的时候 ...
- VS2013中使用GDI+绘图
VC范例,400多个例子源代码下载 http://download.csdn.net/detail/bigtree_mfc/7727977 VS2013中使用GDI+绘图和VC6.0不同,在VC6.0 ...
- Gdi绘图
在使用VC开发项目过程中,界面是项目中的一个子模块.虽然界面并不那么重要,把握住核心功能就可以了,但界面美观与否直接关系到用户的体验, 因此我们也应该关注界面的处理. 我们可以在OnEraseBkgn ...
- GDI+(一):GDI+ 绘图基础
一.GDI+绘图基础 编写图形程序时需要使用GDI(Graphics Device Interface,图形设备接口),从程序设计的角度看,GDI包括两部分:一部分是GDI对象,另一部分是GDI函数. ...
- Windows GDI绘图基础知识
一.Windows可以画直线.椭圆线(椭圆圆周上的曲线)和贝塞尔曲线.////////////7 个画线函式是:(1)画直线LineTo BOOL LineTo(HDC hdc,int nXEn ...
- GDI绘图中的映射模式CDC::SetMapMode()
原文链接:http://blog.csdn.net/charlessimonyi/article/details/8264572 在GDI绘图前,一般要设置映射模式.映射模式是什么呢?它是逻辑长度单位 ...
- GDI+绘图基础
GDI+ 指的是.NET Framwork中提供的二维图像.图像处理等功能,是构成Windows操作系统的一个子系统,它提供了图形图像操作的应用程序编程接口(API). 使用GDI+可以用相同的方式在 ...
随机推荐
- Docker Toolbox常见错误解决方案
错误1 Error checking TLS connection: Error checking and/or regenerating the certs: There was an error ...
- 10g RAC常用开启关闭命令 – SRVCTL用法
10G RAC: srvctl 1. Grammar: srvctl <command> <object> [<options]] available <comma ...
- PHP中的traits简单理解
Traits可以理解为一组能被不同的类都能调用到的方法集合,但Traits不是类!不能被实例化.先来例子看下语法: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1 ...
- Rhel5.5配置Centos yum源
ruiy哥,抛砖引玉 当你使用rhel系统时,[大部分数据库中心及政府企业选择linux服务器时通常考虑采购的版本一般不外乎是Rhel红帽及Suse,理由你懂的EcoSystem!]你没有一个红帽网络 ...
- 关于where和having的直观理解
一,查询区别 where是对前面select的字段没有要求,直接查询库表的 having是对前面的select的字段有要求,字段已经select出来的 可以用having进行处理 select id, ...
- sysbench基准测试(2)——oltp.lua测试
前面知道sysbench基准测试的主要步骤为:prepare(准备数据集)→ run(运行测试)→ cleanup(清除数据集) 这一节介绍oltp.lua测试. oltp基准测试模拟了一个简单的事物 ...
- datagridview绑定xml
//加载描述的XML private bool loadXML() { //创建DataTable对象dt DataTable dt = new DataTable("clientXML&q ...
- __slots__
__slots__ 由于Python是动态语言,任何实例在运行期都可以动态地添加属性. 如果要限制添加的属性,例如,Student类只允许添加 name.gender和score 这3个属性,就可以利 ...
- **python中的类和他的成员
面向对象是一种编程方式,此编程方式的实现基于对 类 和 对象 的使用. Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的. 在这里,为文章中使用 ...
- maven surefire plugin介绍
示例 <!-- 测试运行器,生成测试报告 --> <plugin> <groupId>org.apache.maven.plugins</groupId> ...