Visual C# 2005 - 如何利用程序代码产生多层次绘图效果

 

看完前一篇「如何利用程序代码制作简单动画效果」文章之后,可以制作简单动画效果,接下来,要更进一步运用 .Net Framework System.Drawing System.Drawing.Drawing2D 命名空间中的 GraphicsSolidBrushHatchBrushTextureBrushLinearGradientBrushPointPathGradientBrush 以及 Pen 类别,制作媲美专业绘图软件的图像、实线笔刷、缝影线笔刷、纹理、线性渐层、与路径渐层。 

 

程序范例 


图表1 

图表 1 是我们所撰写之程序的执行画面,它示范如何提供笔刷类型、绘图样式、前景与背景颜色、笔刷尺寸、拼接、花纹以及翻转、渐层等各种选项,用户设定完毕之后,程序会自动根据不同的选项将图像绘制于右方的 PictureBox 控件中,程序设计重点说明如下。 

 

在窗体的 Load 事件处理例程中,除了将组件的 AsmFQName 属性值指派给窗体的  Text  属性之外,特别要说明的是,如果您希望在程序执行阶段将子项目加入 ComboBox 控件,请采用 comboBox.Items.Add(Item) 方法,完整的程序代码如下所示: 

 

private void Blog_DemoForm005_Load(object sender, EventArgs e)
{
 AssemblyInfoClass myAssembly = new AssemblyInfoClass();
 
 this.Text = myAssembly.AsmFQName;
 
 m_BrushSize = new Rectangle(0, 0, picDemoArea.Width,
   picDemoArea.Height);
 
 //
将弯曲变换模式加入ComboBox 当作子项目。
 cboWrapMode.Items.Add(WrapMode.Clamp);
 cboWrapMode.Items.Add(WrapMode.Tile);
 cboWrapMode.Items.Add(WrapMode.TileFlipX);
 cboWrapMode.Items.Add(WrapMode.TileFlipY);
 cboWrapMode.Items.Add(WrapMode.TileFlipXY);
 
 const int maxHatchStyle = 52;
 
 for(int i = (int)HatchStyle.Min;i <= maxHatchStyle;i++)
 {
  cboHatchStyle.Items.Add((HatchStyle)(i));
 }
 
 //
将线形渐层的方向加入ComboBox 当作子项目。
 cboGradientMode.Items.Add(
   LinearGradientMode.BackwardDiagonal)
;
 cboGradientMode.Items.Add(
   LinearGradientMode.ForwardDiagonal)
;
 cboGradientMode.Items.Add(LinearGradientMode.Horizontal);
 cboGradientMode.Items.Add(LinearGradientMode.Vertical);
 
 //
设定窗体ComboBox 控件默认值。
 cboBrushSize.SelectedIndex = 0;
 cboGradientMode.SelectedIndex = 0;
 cboHatchStyle.SelectedIndex = 0;
 cboWrapMode.SelectedIndex = 0;
}


要让用户选择前景与背景颜色,利用 ColorDialog  类别来显示「色彩」对话框最为简便,相关程序代码撰写于 btnSetColor1 btnSetColor2 按钮的 Click 事件处理例程,列示如下: 

private void btnSetColor1_Click(object sender, EventArgs e)
{
 ColorDialog cdlg = new ColorDialog();
 
 //
开启色彩对话框。
 if (cdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
 {
  m_Color1 = cdlg.Color;
  txtColor1.Text = cdlg.Color.ToString();
  txtColor1.BackColor = cdlg.Color;
 }
}

private void btnSetColor2_Click(object sender, EventArgs e)
{
 ColorDialog cdlg = new ColorDialog();
 
 //
开启色彩对话框。
 if (cdlg.ShowDialog() == System.Windows.Forms.DialogResult.OK)
 {
  m_Color2 = cdlg.Color;
  txtColor2.Text = cdlg.Color.ToString();
  txtColor2.BackColor = cdlg.Color;
 }
}

当用户选择不同的笔刷尺寸之后,会产生以原点(也就是X轴坐标为零且Y轴坐标为零)为基准,不同大小的矩型参数,并重新绘制图像(程序代码撰写于 cboBrushSize 控件的 SelectedIndexChanged 事件处理例程):


private void cboBrushSize_SelectedIndexChanged(
  object sender, EventArgs e)
{
 //
判断笔刷尺寸。
 switch(cboBrushSize.Text)
 {
  case "
" :
    m_BrushSize =
      new Rectangle(
      0, 0, picDemoArea.Width, picDemoArea.Height);
    break;
  case "
" :
    m_BrushSize =
      new Rectangle(
      0, 0, picDemoArea.Width / 2, picDemoArea.Height / 2);
    break;
  case "
" :
    m_BrushSize =
      new Rectangle(
      0, 0, picDemoArea.Width / 4, picDemoArea.Height / 4);
    break;
 }
 
 //
重新绘制图片。
 RedrawPicture(cboBrushSize, new EventArgs());
}

cboBrushSize 控件的 SelectedIndexChanged 事件处理例程会叫用自订函式 RedrawPicture 来重置 PictureBox 及状态列信息,同时函式会根据用户设定的笔刷类型与绘图样式参数重绘图像,兹将程序代码列示如下:


private void RedrawPicture(
  System.Object sender, System.EventArgs e)
{
 //
重置PictureBox
 picDemoArea.CreateGraphics().Clear(Color.White);
 picDemoArea.Refresh();
 
 //
重置状态列。
 this.toolStripStatusLabel1.Text = "";
 
 //
判断笔刷类型。
 switch(cboBrushType.Text)
 {
  case "
实线" :
   
    SolidBrush mySolidBrush = new SolidBrush(m_Color1);
   
    m_Brush = mySolidBrush;
   
    break;
  case "
缝影线" :
   
    HatchBrush myHatchBrush =
      new HatchBrush(
      (HatchStyle)(cboHatchStyle.SelectedItem),
      m_Color1, m_Color2)
;
   
    m_Brush = myHatchBrush;
   
    break;
  case "
纹理" :
   
    TextureBrush myTextureBrush = new TextureBrush(
      new Bitmap(Resources.WaterLilies), m_BrushSize)
;
   
    myTextureBrush.WrapMode =
      (WrapMode)(cboWrapMode.SelectedItem);
   
    myTextureBrush.RotateTransform((float)nudRotation.Value);
   
    m_Brush = myTextureBrush;
   
    break;
  case "
线性渐层" :
   
    LinearGradientBrush myLinearGradientBrush =
      new LinearGradientBrush(
      m_BrushSize, m_Color1, m_Color2,
      (LinearGradientMode)(cboGradientMode.SelectedItem))
;
   
    if((WrapMode)(cboWrapMode.SelectedItem) != WrapMode.Clamp)
    {
     myLinearGradientBrush.WrapMode =
       (WrapMode)(cboWrapMode.SelectedItem);
    }
    else
    {
     this.toolStripStatusLabel1.Text +=
       "
线型渐层笔刷不能使用在Clamp 拼接模式。";
    }
   
    myLinearGradientBrush.RotateTransform(
      (float)nudRotation.Value);
   
    myLinearGradientBrush.SetBlendTriangularShape(
      (float)nudGradientBlend.Value);
   
    m_Brush = myLinearGradientBrush;
   
    break;
  case "
路径渐层" :
   
    Point[] pathPoint = new Point[]
    {
     new Point(0, m_BrushSize.Height),
     new Point(m_BrushSize.Width, m_BrushSize.Height),
     new Point(m_BrushSize.Width, 0)
    };
   
    PathGradientBrush myPathGradientBrush =
      new PathGradientBrush(pathPoint);
   
    myPathGradientBrush.CenterColor = m_Color1;
   
    myPathGradientBrush.SurroundColors =
      new Color[] {m_Color2};
   
    myPathGradientBrush.WrapMode =
      (WrapMode)(cboWrapMode.SelectedItem);
   
    myPathGradientBrush.RotateTransform(
      (float)nudRotation.Value);
   
    myPathGradientBrush.SetBlendTriangularShape(
      (float)nudGradientBlend.Value);
   
    m_Brush = myPathGradientBrush;
   
    break;
 }
 
 myGraphics = picDemoArea.CreateGraphics();
 
 //
判断绘图样式。
 switch(cboDrawing.Text)
 {
  case "
填满" :
    myGraphics.FillRectangle(m_Brush, 0, 0,
      picDemoArea.Width, picDemoArea.Height);
    break;
  case "
椭圆" :
    myGraphics.FillEllipse(m_Brush, picDemoArea.Width / 10,
      picDemoArea.Height / 10, picDemoArea.Width / 2,
      picDemoArea.Height / 2);
    myGraphics.FillEllipse(m_Brush, picDemoArea.Width / 3,
      picDemoArea.Height / 3, picDemoArea.Width / 2,
      picDemoArea.Height / 2);
    break;
  case "
线形" :
    Pen myPen = new Pen(m_Brush, 40);
   
    myGraphics.DrawLine(
      myPen, 0, 0, picDemoArea.Width, picDemoArea.Height);
    myGraphics.DrawLine(myPen, 0, 0, 0, picDemoArea.Height);
    myGraphics.DrawLine(myPen, 0, 0, picDemoArea.Width, 0);
    myGraphics.DrawLine(myPen, picDemoArea.Width, 0,
      picDemoArea.Width, picDemoArea.Height);
    myGraphics.DrawLine(myPen, 0, picDemoArea.Height,
      picDemoArea.Width, picDemoArea.Height);
    myGraphics.DrawLine(
      myPen, picDemoArea.Width, 0, 0, picDemoArea.Height);
    break;
 }
 
 //
显示状态列讯息。
 if (this.toolStripStatusLabel1.Text == "")
 {
  this.toolStripStatusLabel1.Text = "
成功!";
 }
}

最后,本程序范例的执行结果如图表 2 5 所示。



图表
2


图表3


图表4 


图表 5

 

posted on 2006-11-13 10:51  章立民研究室  阅读(3610)  评论(2编辑  收藏  举报

导航