GDI+编程10个基本技巧

创建绘图表面
  创建绘图表面有两种常用的方法。下面设法得到PictureBox的绘图表面。
  private void Form1_Load(object sender, System.EventArgs e)
  {
  //得到pictureBox1的绘图表面
  Graphics g = this.pictureBox1.CreateGraphics();
  }
  private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
  {
  //得到pictureBox1的绘图表面
  Graphics g = e.Graphics;
  }
  可以利用Graphics对象绘制出各种图形图案。控件的Paint事件和OnPaint方法都可以绘图都是好时机。在OnPaint方法里绘制图案一定从参数e里面得到Graphics属性。下面是两个例子。
  protected override void OnPaint(PaintEventArgs e)
  {
  e.Graphics.Clear(Color.White);
  float x, y, w, h;
  x = this.Left+2;
  y = this.Top+2;
  w = this.Width-4;
  h = this.Height-4;
  Pen pen = new Pen(Color.Red, 2);
  e.Graphics.DrawRectangle(pen, x, y, w, h);
  base.OnPaint (e);
  }
  private void PictureBoxII_Resize(object sender, EventArgs e)
  {
  this.Invalidate();
  }
  private void button1_Click(object sender, System.EventArgs e)
  {
  this.pictureBoxII1.CreateGraphics().FillEllipse(
  Brushes.Blue, 10, 20, 50, 100);
  }
  和文本有关的三个类:
  FontFamily——定义有着相似的基本设计但在形式上有某些差异的一组字样。无法继承此类。
  Font——定义特定的文本格式,包括字体、字号和字形属性。无法继承此类。
  StringFormat——封装文本布局信息(如对齐方式和行距),显示操作(如省略号插入和国家标准 (National) 数字位替换)和 OpenType 功能。无法继承此类。
  下面的程序显示了一段文字。
  private void button2_Click(object sender, System.EventArgs e)
  {
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.FillRectangle(Brushes.White, this.pictureBoxII1.ClientRectangle);
  string s = "aaaaaaaaaaaaaaaaaaaaaaaaaa";
  FontFamily fm = new FontFamily("ËÎÌå");
  Font f = new Font(fm, 20, FontStyle.Bold, GraphicsUnit.Point);
  RectangleF rectF = new RectangleF(30, 20, 180, 205);
  StringFormat sf = new StringFormat();
  SolidBrush sbrush = new SolidBrush(Color.FromArgb(255, 0, 0, 255));
  sf.LineAlignment = StringAlignment.Center;
  sf.FormatFlags = StringFormatFlags.DirectionVertical;
  g.DrawString(s, f, sbrush, rectF, sf);
  }
  GDI+的路径——GraphicsPath类
  GraphicsPath类提供了一系列属性和方法,利用它可以获取路径上的关键点,可以添加直线段、圆等几何元素。可以获得包围矩形,进行拾取测试。这些功能都怎么用,要仔细看一下。
  private void button3_Click(object sender, System.EventArgs e)
  {
  //绘图表面
  Graphics g = this.pictureBoxII1.CreateGraphics();
  //填充成白色
  g.FillRectangle(Brushes.White, this.ClientRectangle);
  //弄一个绘图路径¶
  GraphicsPath gp = new GraphicsPath();
  //添加一些集合图形
  gp.AddEllipse(20, 20, 300, 200);
  gp.AddPie(50, 100, 300, 100, 45, 200);
  gp.AddRectangle(new Rectangle(100, 30, 100, 80));
  //在绘图表面上绘制绘图路径
  g.DrawPath(Pens.Blue, gp);
  //平移
  g.TranslateTransform(200, 20);
  //填充绘图路径¶
  g.FillPath(Brushes.GreenYellow, gp);
  gp.Dispose();
  }
  区域——Region类
  从已有的矩形和路径可以创建Region。使用Graphics.FillRegion方法绘制Region。该类指示由矩形和由路径构成的图形形状的内部。无法继承此类。
  渐变色填充
  需要使用两个刷子:
  线性梯度刷子(LinearGradientBrush)
  路径梯度刷子(PathGuadientBrush)
  private void button4_Click(object sender, System.EventArgs e)
  {
  //绘图表面
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.FillRectangle(Brushes.White, this.pictureBoxII1.ClientRectangle);
  //定义一个线性梯度刷子
  LinearGradientBrush lgbrush =
  new LinearGradientBrush(
  new Point(0, 10),
  new Point(150, 10),
  Color.FromArgb(255, 0, 0),
  Color.FromArgb(0, 255, 0));
  Pen pen = new Pen(lgbrush);
  //用线性笔刷梯度效果的笔绘制一条直线段并填充一个矩形
  g.DrawLine(pen, 10, 130, 500, 130);
  g.FillRectangle(lgbrush, 10, 150, 370, 30);
  //定义路径并添加一个椭圆
  GraphicsPath gp = new GraphicsPath();
  gp.AddEllipse(10, 10, 200, 100);
  //用该路径定义路径梯度刷子
  PathGradientBrush brush =
  new PathGradientBrush(gp);
  //颜色数组
  Color[] colors = {
  Color.FromArgb(255, 0, 0),
  Color.FromArgb(100, 100, 100),
  Color.FromArgb(0, 255, 0),
  Color.FromArgb(0, 0, 255)};
  //定义颜色渐变比率
  float[] r = {0.0f, 0.3f, 0.6f, 1.0f};
  ColorBlend blend = new ColorBlend();
  blend.Colors = colors;
  blend.Positions = r;
  brush.InterpolationColors = blend;
  //在椭圆外填充一个矩形
  g.FillRectangle(brush, 0, 0, 210, 110);
  //用添加了椭圆的路径定义第二个路径梯度刷子
  GraphicsPath gp2 = new GraphicsPath();
  gp2.AddEllipse(300, 0, 200, 100);
  PathGradientBrush brush2 = new PathGradientBrush(gp2);
  //设置中心点位置和颜色
  brush2.CenterPoint = new PointF(450, 50);
  brush2.CenterColor = Color.FromArgb(0, 255, 0);
  //设置边界颜色
  Color[] color2 = {Color.FromArgb(255, 0, 0)};
  brush2.SurroundColors = color2;
  //用第二个梯度刷填充椭圆
  g.FillEllipse(brush2, 300, 0, 200, 100);
  }
  GDI+的坐标系统
  通用坐标系——用户自定义坐标系。
  页面坐标系——虚拟坐标系。
  设备坐标系——屏幕坐标系。
  当页面坐标系和设备坐标系的单位都是象素时,它们相同。
  private void button10_Click(object sender, System.EventArgs e)
  {
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  this.Draw(g);
  }
  private void Draw(Graphics g)
  {
  g.DrawLine(Pens.Black, 10, 10, 100, 100);
  g.DrawEllipse(Pens.Black, 50, 50, 200, 100);
  g.DrawArc(Pens.Black, 100, 10, 100, 100, 20, 160);
  g.DrawRectangle(Pens.Green, 50, 200, 150, 100);
  }
  private void button5_Click(object sender, System.EventArgs e)
  {
  //左移
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  g.TranslateTransform(-50, 0);
  this.Draw(g);
  }
  private void button6_Click(object sender, System.EventArgs e)
  {
  //右移
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  g.TranslateTransform(50, 0);
  this.Draw(g);
  }
  private void button7_Click(object sender, System.EventArgs e)
  {
  //旋转
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  g.RotateTransform(-30);
  this.Draw(g);
  }
  private void button8_Click(object sender, System.EventArgs e)
  {
  //放大
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  g.ScaleTransform(1.2f, 1.2f);
  this.Draw(g);
  }
  private void button9_Click(object sender, System.EventArgs e)
  {
  //缩小
  Graphics g = this.pictureBoxII1.CreateGraphics();
  g.Clear(Color.White);
  g.ScaleTransform(0.8f, 0.8f);
  this.Draw(g);
  }
  全局坐标——变换对于绘图表面上的每个图元都会产生影响。通常用于设定通用坐标系。
  一下程序将原定移动到控件中心,并且Y轴正向朝上。
  //先画一个圆
  Graphics g = e.Graphics;
  g.FillRectangle(Brushes.White, this.ClientRectangle);
  g.DrawEllipse(Pens.Black, -100, -100, 200, 200);
  //使y轴正向朝上,必须做相对于x轴镜像
  //变换矩阵为[1,0,0,-1,0,0]
  Matrix mat = new Matrix(1, 0, 0, -1, 0, 0);
  g.Transform = mat;
  Rectangle rect = this.ClientRectangle;
  int w = rect.Width;
  int h = rect.Height;
  g.TranslateTransform(w/2, -h/2);
  //以原点为中心,做一个半径为100的圆
  g.DrawEllipse(Pens.Red, -100, -100, 200, 200);
  g.TranslateTransform(100, 100);
  g.DrawEllipse(Pens.Green, -100, -100, 200, 200);
  g.ScaleTransform(2, 2);
  g.DrawEllipse(Pens.Blue, -100, -100, 200, 200);
  局部坐标系——只对某些图形进行变换,而其它图形元素不变。
  protected override void OnPaint(PaintEventArgs e)
  {
  Graphics g = e.Graphics;
  //客户区设置为白色
  g.FillRectangle(Brushes.White, this.ClientRectangle);
  //y轴朝上
  Matrix mat = new Matrix(1, 0, 0, -1, 0, 0);
  g.Transform = mat;
  //移动坐标原点到窗体中心
  Rectangle rect = this.ClientRectangle;
  int w = rect.Width;
  int h = rect.Height;
  g.TranslateTransform(w/2, -h/2);
  //在全局坐标下绘制椭圆
  g.DrawEllipse(Pens.Red, -100, -100, 200, 200);
  g.FillRectangle(Brushes.Black, -108, 0, 8, 8);
  g.FillRectangle(Brushes.Black, 100, 0, 8, 8);
  g.FillRectangle(Brushes.Black, 0, 100, 8, 8);
  g.FillRectangle(Brushes.Black, 0, -108, 8, 8);
  //创建一个椭圆然后在局部坐标系中进行变换
  GraphicsPath gp = new GraphicsPath();
  gp.AddEllipse(-100, -100, 200, 200);
  Matrix mat2 = new Matrix();
  //平移
  mat2.Translate(150, 150);
  //旋转
  mat2.Rotate(30);
  gp.Transform(mat2);
  g.DrawPath(Pens.Blue, gp);
  PointF[] p = gp.PathPoints;
  g.FillRectangle(Brushes.Black, p[0].X-2, p[0].Y+2, 4, 4);
  g.FillRectangle(Brushes.Black, p[3].X-2, p[3].Y+2, 4, 4);
  g.FillRectangle(Brushes.Black, p[6].X-4, p[6].Y-4, 4, 4);
  g.FillRectangle(Brushes.Black, p[9].X-4, p[9].Y-4, 4, 4);
  gp.Dispose();
  //base.OnPaint (e);
  }
  Alpha混合
  Color.FromArgb()的A就是Alpha。Alpha的取值范围从0到255。0表示完全透明,255完全不透明。
  当前色=前景色×alpha/255+背景色×(255-alpha)/255
  protected override void OnPaint(PaintEventArgs e)
  {
  Graphics g = e.Graphics;
  //创建一个填充矩形
  SolidBrush brush = new SolidBrush(Color.BlueViolet);
  g.FillRectangle(brush, 180, 70, 200, 150);
  //创建一个位图,其中两个位图之间有透明效果
  Bitmap bm1 = new Bitmap(200, 100);
  Graphics bg1 = Graphics.FromImage(bm1);
  SolidBrush redBrush =
  new SolidBrush(Color.FromArgb(210, 255, 0, 0));
  SolidBrush greenBrush =
  new SolidBrush(Color.FromArgb(210, 0, 255, 0));
  bg1.FillRectangle(redBrush, 0, 0, 150, 70);
  bg1.FillRectangle(greenBrush, 30, 30, 150, 70);
  g.DrawImage(bm1, 100, 100);
  //创建一个位图,其中两个位图之间没有透明效果
  Bitmap bm2 = new Bitmap(200, 100);
  Graphics bg2 = Graphics.FromImage(bm2);
  bg2.CompositingMode = CompositingMode.SourceCopy;
  bg2.FillRectangle(redBrush, 0, 0, 150, 170);
  bg2.FillRectangle(greenBrush, 30, 30, 150, 70);
  g.CompositingQuality = CompositingQuality.GammaCorrected;
  g.DrawImage(bm2, 300, 200);
  //base.OnPaint (e);
  }
  
  反走样
  protected override void OnPaint(PaintEventArgs e)
  {
  Graphics g = e.Graphics;
  //放大8倍
  g.ScaleTransform(8, 8);
  //没有反走样的图形和文字
  Draw(g);
  //设置反走样
  g.SmoothingMode = SmoothingMode.AntiAlias;
  //右移40
  g.TranslateTransform(40, 0);
  //再绘制就是反走样之后的了
  Draw(g);
  //base.OnPaint (e);
  }
  private void Draw(Graphics g)
  {
  //绘制图形和文字
  g.DrawLine(Pens.Gray, 10, 10, 40, 20);
  g.DrawEllipse(Pens.Gray, 20, 20, 30, 10);
  string s = "反走样测试";
  Font font = new Font("宋体", 5);
  SolidBrush brush = new SolidBrush(Color.Gray);
  g.DrawString(s, font, brush, 10, 40);
  }
  完了。暂时先总结那么多。以后发现必要的可以再补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值