【GDI+编程】--从三问开始
一、 GDI+三问
1.1 GDI+是什么?
GDI+是GDI(Graphics Device Interface)的后继者,是一种图形设备的接口,它构成了Win XP操作系统的子系统的API。
1.2 GDI+能做什么?
GDI+能够在绘图界面上绘制我们想要的图形。如:对数据进行统计后得到的柱状图或曲线图等。
绘图界面:一般来说有3中基本的用于绘图的界面,分行别是Windows窗体上的控件、要发给打印机的界面和内存中的位图和图像。
1.3 怎么做呢?
在GDI+中我们可以把它分为两种,一种是绘图界面,另一种则是构造块,绘图界面即为上面所说的容器,那构造块呢?程序开发过程中,GDI+中的一些基本构造块可用于绘制二维图形,GDI+支持的基本构造块有:直线、矩形、椭圆、弧线、多边形、基数样条和贝塞尔样条等。
1.3.1 如何绘图:Graphics类
Graphics类封装了一个GDI+绘图界面,该类提供了可以在以上3种绘图界面上绘图的功能,开发人员可以使用该类来绘制文本、线条、矩形、曲线、多边形、椭圆、圆弧和贝塞尔样条等。
Graphics类提供了绘制基本构造块的各种方法,包括DrawLine、DrawRectangle、DrawEllipse、DrawPolygon、DrawArc、DrawCurve(针对基数样条)和DrawBezier等。这些方法中的每一种都可以重载。例如,DrawLine方法的一种形式接收一个Pen对象和4个整数,而它的另一种形式则接收一个Pen对象和两个Point对象。
Graphics类的所有绘制方法都应与Pen对象一起使用。若要进行图形绘制,至少必须创建两个对象:Graphics对象和Pen对象。
另外,绘制直线、矩形和贝塞尔样条的方法具有多个伴随方法,可在一个调用中绘制如下项:DrawLines、DrawRectangles和DrawBeziers。DrawCurve方法也有一个伴随方法DrawClosedCurve,该伴随方法能够通过连接曲线起点和终点的方式来闭合曲线。
二、实例详解
2.1 区域剪辑与填充
上篇中对GDI+基本的概念详述了一遍,通过GDI+能够绘制二维图像,并说到了能够绘制基本构造块的Graphics方法。该篇将会从上篇基础上更深入的讨论GDI+的基本用法,并通过实例来了解Region、GraphicsPath和Brush的使用。
下面的示例分别在窗体上绘制了两个图形,图形1为区域截取即指定了绘图区域的大小,并使用SetClip方法来组合剪辑区域;图形2为矩形填充区域,使用红色作为边界,并使用蓝色填充矩形内部。
/// <summary>
/// 剪辑区域绘制事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics(); //创建一个绘图界面 //创建一个绘图区域,并将绘图区域与图形路径进行拼合,实现图形区域截取
Point[] p = { new Point(50, 50), new Point(150, 30), new Point(150, 150), new Point(60, 150) }; //创建坐标点数组用来指定所绘制的图形四周的顶点坐标
GraphicsPath gp = new GraphicsPath(); // 创建一个图形路径,用来指定所绘制的图形
gp.AddPolygon(p); //在此路径中添加所画的多边形 Region r = new Region(new Rectangle(new Point(50, 50), new Size(200, 200))); //创建一个绘图区域
r.Intersect(gp); //将指定的区域更新为r和gp的交集 Pen mypen = new Pen(Color.Blue, 3); //创建一个Pen对象
g.DrawPath(mypen, gp); //在g中绘制所创建的路径gp g.SetClip(r, CombineMode.Replace); //组合剪辑区域r
//使用DrawString方法在绘图界面上绘制字符串为“GDI+区域”
g.DrawString("GDI+区域", new Font(new FontFamily("宋体"), 36, FontStyle.Regular, GraphicsUnit.Pixel), new SolidBrush(Color.Red), new PointF(50, 60));
} /// <summary>
/// 填充矩形绘制事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
Graphics g = this.CreateGraphics(); //创建一个图形绘制界面 Rectangle rec = new Rectangle(200, 30, 200, 200); //创建一个矩形绘制区域
g.DrawRectangle(new Pen(Color.Red, 2), rec); //绘制该矩形区域的四边
g.FillRectangle(new SolidBrush(Color.Blue), rec); //只用指定的颜色填充矩形区域 }
上面两种绘图本质上是相同的,首先创建一个绘图界面,然后创建绘图区域,其次在绘图界面中获取绘图区域,最后绘制区域。
图形2的绘制很简单,来看看图形1的绘制。对于图形1绘制的区域是路径区域,使用了GraphicsPath只要为它指定了相应的坐标点后,就能够画出任意形状的多边形,最终的功劳应该归功于AddPolygon方法,该方法实现了任意多边形的绘制。其次使用Region类来创建剪辑区域,创建剪辑后需要把该区域与需要被剪辑的区域组合,于是使用了Graphics的SetClip方法实现了两个绘图区域的剪辑组合。
2.2 圆角矩形
上例从基本的图形绘制出发,绘制了两种图形,只要能熟练使用这几种类就能够很快的绘制出想要的图形。接下来看一个圆角矩形的绘制过程。
清单1:封装画法的圆角矩形类。该类封装了具体的圆角矩形的画法,大致的思路是首先分别绘制出矩形的四个圆角,然后使用CloseFigure方法,闭合该区域。当然绘制方法还有很多种,可以自己去研究。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Text; namespace Draw
{
public class RoundRectangle
{
/// <summary>
/// 封装的圆角矩形画法
/// </summary>
/// <param name="g">传引用:图形界面对象</param>
/// <param name="rect">传引用:图形绘制的区域大小</param>
/// <param name="wid">圆角半径值</param>
/// <param name="p">圆角矩形的边框的样式</param>
/// <param name="sb">圆角矩形内部填充样式</param>
public void DrawRoundRectanle(ref Graphics g,ref Rectangle rect,int wid,Pen p,SolidBrush sb) { GraphicsPath gp = new GraphicsPath(); //创建一个图形绘制路径
gp.AddArc(rect.X, rect.Y, wid * 2, wid * 2, 180, 90); //绘制左上圆角
gp.AddArc(rect.X + rect.Width - wid * 2, rect.Y, wid * 2, wid * 2, 270, 90); //绘制右上圆角
gp.AddArc(rect.X + rect.Width - wid * 2, rect.Y + rect.Height - wid * 2, wid * 2, wid * 2, 0, 90); //绘制右下圆角
gp.AddArc(rect.X, rect.Y + rect.Height - wid * 2, wid * 2, wid * 2, 90, 90); //绘制左下圆角
gp.CloseFigure(); //闭合圆角区域,成为一个闭合图形 g.SmoothingMode = SmoothingMode.AntiAlias; //边框消除锯齿
g.DrawPath(p, gp); //绘制路径
g.FillPath(sb, gp); //填充圆角矩形内部
}
}
}
清单2:圆角矩形绘制事件。单击按钮后绘制出想要的大小的圆角矩形。
/// <summary>
/// 剪辑区域绘制事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{ Graphics g =this.panel1.CreateGraphics(); //创建一个绘图界面
RoundRectangle rr = new RoundRectangle(); //创建圆角矩形绘制对象
int wid = 10; //确定圆角半径
//创建绘制区域
Rectangle rect=new Rectangle (new Point (panel1 .Location .X ,panel1 .Location .Y ),new Size (200,200));
//创建边框和填充样式
Pen p=new Pen (Color .FromArgb (106,154,193),2);
SolidBrush sb = new SolidBrush(Color.FromArgb(106, 154, 193));
//绘制区域
rr.DrawRoundRectanle (ref g,ref rect,wid,p,sb);
}
三、结语
GDI+图形图像的绘制其实是在封装了底层API后展示给开发人员的一个接口,这是利用了.NET平台的特性,绘制的方法比较简单,主要是几个类的使用,另外想要绘制出想要的图形界面必须对绘制的图形进行计算。同时利用GDI+也可以绘制出数据统计图,只要知道了绘制方法,它会比MSChart控件灵活的多,至于画法将会在接下来的文章中陆续更新。
【GDI+编程】--从三问开始的更多相关文章
- GDI编程小结
图形设备接口(GDI)是一个可运行程序,它接受Windows应用程序的画图请求(表现为GDI函数调用),并将它们传给对应的设备驱动程序,完毕特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...
- GDI+编程说明及小结
原文地址:http://blog.csdn.net/byxdaz/article/details/5972759 GDI+(Graphics Device Interface Plus图形设备接口加) ...
- 转:JavaScript函数式编程(三)
转:JavaScript函数式编程(三) 作者: Stark伟 这是完结篇了. 在第二篇文章里,我们介绍了 Maybe.Either.IO 等几种常见的 Functor,或许很多看完第二篇文章的人都会 ...
- GDI编程
图形设备接口(GDI)是一个可执行程序,它接受Windows应用程序的绘图请求(表现为GDI函数调用),并将它们传给相应的设备驱动程序,完成特定于硬件的输出,象打印机输出和屏幕输出.GDI负责Wind ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...
- MFC控件GDI编程
MFC控件GDI编程 一丶学习内容 1.了解常用的GDI函数绘图. 2.使用常用的画笔画刷. 二丶常用的GDI函数绘图 上方则为我们常用的GDI函数了. 画线 矩形. 以及圆 等等. 2.1 画线代码 ...
- 斐波那契数列-java编程:三种方法实现斐波那契数列
题目要求:编写程序在控制台输出斐波那契数列前20项,每输出5个数换行 斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, … 这个数列 ...
- GDI+编程小结
GDI+(Graphics Device Interface Plus图形设备接口加)是Windows XP和Windows Server 2003操作系统的子系统,也是.NET框架的重要组成部分,负 ...
- 并发编程(三)Promise, Future 和 Callback
并发编程(三)Promise, Future 和 Callback 异步操作的有两个经典接口:Future 和 Promise,其中的 Future 表示一个可能还没有实际完成的异步任务的结果,针对这 ...
随机推荐
- SSL VPN 详解
SSL VPN是专栏VPN系列技术原理的最后一篇,SSL VPN作为远程接入型的VPN,已经具备非常广阔的前景,它的主要适应场景是取代L2TP Over IPSec,但功能要比L2TP Over IP ...
- 实现Bootstrap Carousel Fade Transition 淡入淡出效果
html代码: <div id="carousel" class="carousel slide carousel-fade" data-ride=&qu ...
- Junit4_单元测试
不多说,直接练习学习. 1.将Junit4单元测试包引入项目:项目右键——“属性”,选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Libr ...
- hbase的存储体系
一.了解hbase的存储体系. hbase的存储体系核心的有Split机制,Flush机制和Compact机制. 1.split机制 每一个hbase的table表在刚刚开始的时候,只有一个regio ...
- Sqoop import加载HBase过程中,遇到Permission denied: user=root, access=WRITE, inode="/user":hdfs:supergroup:drwxr-xr-x
在执行hbase sqoop抽取的时候,遇到了一个错误,如下图: 在执行程序的过程中,遇到权限问题很正常,也容易让人防不胜防,有问题就想办法解决,这个是关键. 解决办法如下: 第一步:su hdfs, ...
- sicily-2499 平方数
题目分析: 一个数可以表示成四种状态,所以可以用一个状态数组来存放该数由几个数的平方和表示.1.表示该数本身是完全平方.2.表示该数是由两个平方和3.表示三个.4.表示4个.一次遍历找出本身是完全平方 ...
- iPhone、iPad默认按钮样式问题
iPhone.iPad默认按钮样式问题 解决方法给按钮元素添加一个-webkit-appearance: none;具体代码 input[type="button"], input ...
- php基础知识【函数】(7)url和ob函数
一.URl函数 1.urlencode -- 编码 URL 字符串 2.urldecode -- 解码已编码的 URL 字符串 3.rawurlencode -- 按照 RFC 1738 对 URL ...
- NSDictionary 使用总结
NSDictionary使用小结 #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @ ...
- Java中遍历Map的几种方法
转自: http://blog.csdn.net/wzb56/article/details/7864911 方法分为两类: 一类是基于map的Entry:map.entrySet(); 一类是基 ...