C#绘图

    xiaoxiao2026-05-18  9

    本文转自:http://www.2cto.com/kf/201205/133721.html

    通过本实例了解如何在窗体上绘制各种图形,如矩形、椭圆、线条、文字等。运行效果如下:

     

    实现过程:

    (1) 新建窗体应用程序

    (2) 添加一个MenuScrip控件;添加一个ToolScrip控件。

    在ToolScrip控件中对每个单元,要将DisplayStyle属性改为Text

     

    (3)程序代码。

    1、新建菜单事件主要用白色清除窗体的背景,从而实现“文件新建”功能

    [csharp] private void 新建ToolStripMenuItem_Click(object sender, EventArgs e)        {            Graphics g = this.CreateGraphics();            g.Clear(backColor);            toolStrip1.Enabled = true;            //创建一个Bitmap            theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);            editFileName = "新建文件";            //修改窗口标题            this.Text = "MyDraw\t" + editFileName;            ig = Graphics.FromImage(theImage);            ig.Clear(backColor);        } 

     

    2、打开事件用于打开“打开文件”对话框,并选择相应的图片,将图片绘制到窗体上.

     

     

    [csharp] private void 打开ToolStripMenuItem_Click(object sender, EventArgs e)        {            openFileDialog1.Multiselect = false;            if (openFileDialog1.ShowDialog() == DialogResult.OK)            {                //修改窗口标题                this.Text = "MyDraw\t" + openFileDialog1.FileName;                editFileName = openFileDialog1.FileName;                theImage = Image.FromFile(openFileDialog1.FileName);                Graphics g = this.CreateGraphics();                g.DrawImage(theImage, this.ClientRectangle);                ig = Graphics.FromImage(theImage);                ig.DrawImage(theImage, this.ClientRectangle);                //ToolBar可以使用了                toolStrip1.Enabled = true;            }        } 

    (3) 保存菜单项的Click事件用于将窗体背景保存为BMP格式的图片

    [csharp] private void 保存ToolStripMenuItem_Click(object sender, EventArgs e)          {              saveFileDialog1.Filter = "图像(*.bmp)|*.bmp";              saveFileDialog1.FileName = editFileName;              if (saveFileDialog1.ShowDialog() == DialogResult.OK)              {                  theImage.Save(saveFileDialog1.FileName, ImageFormat.Bmp);                  this.Text = "MyDraw\t" + saveFileDialog1.FileName;                  editFileName = saveFileDialog1.FileName;              }          } 

    (4) 在Paint事件中将Image中保存的图像,绘制出来

    [csharp] private void Form1_Paint(object sender, PaintEventArgs e)         {             //将Image中保存的图像,绘制出来             Graphics g = this.CreateGraphics();             if (theImage != null)             {                 g.Clear(Color.White);                 g.DrawImage(theImage, this.ClientRectangle);             }         } 

     (5)添加Frm_Text.cs文字输入框。

        添加一个Window窗体,取名为Frm_Text,然后对窗体的属性修改:

    把FormBorderStyle属性改为 None;

     

    把Modifiers的属性改为 Public

     

    (6) 在窗体的MouseDown事件中,如果当前绘制的是字符串,在鼠标的当前位置显示文本框;如果绘制的是图开,设置图形的起始位置。

    [cpp] private void Frm_Main_MouseDown(object sender, MouseEventArgs e)        {            if (e.Button == MouseButtons.Left)            {                //如果选择文字输入,则打开strInput窗体                if (drawTool == drawTools.String)                {                    Frm_Text inputBox = new Frm_Text();                    inputBox.StartPosition = FormStartPosition.CenterParent;                    if (inputBox.ShowDialog() == DialogResult.OK)                    {                        Graphics g = this.CreateGraphics();                        Font theFont = this.Font;                        g.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);                        ig.DrawString(inputBox.textBox1.Text, theFont, new SolidBrush(foreColor), e.X, e.Y);                    }                }                //如果开始绘制,则开始记录鼠标位置                else if ((isDrawing = !isDrawing) == true)                {                    startPoint = new Point(e.X, e.Y);                    oldPoint = new Point(e.X, e.Y);                }            }        }   

    (7) 在窗体的MouseMove 事件中,根据鼠标移动的大小绘制指定的图形.

    [cpp] private void Form1_MouseMove(object sender, MouseEventArgs e)  {      Graphics g;      g = this.CreateGraphics();        if (isDrawing)      {          switch (drawTool)          {              case drawTools.None:                  break;              case drawTools.Pen:                  //从上一个点到当前点绘制线段                  g.DrawLine(new Pen(foreColor, 1), oldPoint, new Point(e.X, e.Y));                  ig.DrawLine(new Pen(foreColor, 1), oldPoint, new Point(e.X, e.Y));                  oldPoint.X = e.X;                  oldPoint.Y = e.Y;                  break;              case drawTools.Line:                  //首先恢复此次操作之前的图像,然后再添加Line                  this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));                  g.DrawLine(new Pen(foreColor, 1), startPoint, new Point(e.X, e.Y));                  break;              case drawTools.Ellipse:                  //首先恢复此次操作之前的图像,然后再添加Ellipse                  this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));                  g.DrawEllipse(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);                  break;              case drawTools.Rectangle:                  //首先恢复此次操作之前的图像,然后再添加Rectangle                  this.Frm_Main_Paint(this, new PaintEventArgs(this.CreateGraphics(), this.ClientRectangle));                  g.DrawRectangle(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);                  break;              case drawTools.String:                  break;              case drawTools.Rubber:                  //用背景色绘制宽线段                  g.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));                  ig.DrawLine(new Pen(backColor, 20), oldPoint, new Point(e.X, e.Y));                  oldPoint.X = e.X;                  oldPoint.Y = e.Y;                  break;          }      }  } 

    (8) 在窗体的MouseUp事件中,根据用户选择的画笔,绘制直线,椭圆或矩形等指定图形。

    [csharp] private void Form1_MouseUp(object sender, MouseEventArgs e)          {              isDrawing = false;              switch (drawTool)              {                  case drawTools.Line:                      ig.DrawLine(new Pen(foreColor, 1), startPoint, new Point(e.X, e.Y));                      break;                  case drawTools.Ellipse:                      ig.DrawEllipse(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);                      break;                  case drawTools.Rectangle:                      ig.DrawRectangle(new Pen(foreColor, 1), startPoint.X, startPoint.Y, e.X - startPoint.X, e.Y - startPoint.Y);                      break;              }          } 

    =============================================================================================================

    这里解释为什么在拉直线时线会跟着鼠标动,而用选择画笔时移动鼠标就会画出线。

    这里有两个Graphics:

    (1) 真实的场景graphics.   它它上面画出的画面就是我个看到的画面。

         eg:

                   private void Form1_Paint(object sender, PaintEventArgs e)              {                      //将Image中保存的图像,绘制出来                       Graphics g = this.CreateGraphics();

    (2)做为临时存储用的Graphic.

    它在新建的时候创建:

    [csharp] //创建一个Bitmap             theImage = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);             editFileName = "新建文件";             //修改窗口标题             this.Text = "MyDraw\t" + editFileName;             ig = Graphics.FromImage(theImage);             ig.Clear(backColor); 

    显示出来: 把theImage显示出来就是把以前保存在ig里的东西显示出来了

    [csharp] private void Frm_Main_Paint(object sender, PaintEventArgs e)         {             //将Image中保存的图像,绘制出来             Graphics g = this.CreateGraphics();             if (theImage != null)             {                 g.Clear(Color.White);                 g.DrawImage(theImage, this.ClientRectangle);             }         } 

    在Form1_MouseMove里

    如果是画笔,那么把图像保存到了两个graphic中,这样我们可以看到移动的画,最后也将显示所有画。

    如果直线或矩形,那么只先画到第一个graphics里,在鼠标放开时才画到第二个graphic里。

    转载请注明原文地址: https://ju.6miu.com/read-1309818.html
    最新回复(0)