欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GDI+ 绘制直线、矩形、椭圆

程序员文章站 2022-03-02 10:33:18
...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace GDI_
{

    public partial class Form1 : Form
    {
        private DrawTools dt;
        private string _sType;
        public Form1()
        {
            InitializeComponent();
        }
        private void pbImg_MouseDown(object sender,MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            { 
                if(dt != null)
                {
                    dt.startDraw = true;
                    dt.startPointF = new PointF(e.X, e.Y);
                }
            }
        }
        private void pbImg_MouseMove(object sender, MouseEventArgs e)
        {
            if (dt.startDraw)
            { 
                switch (_sType)
                {
                    default:dt.Draw(e, _sType);break;
                }
            }
        }
        private void pbImg_MouseUp(object sender, MouseEventArgs e)
        {
            if(dt!=null)
            {
                dt.EndDraw();
            }
        }
        private void tool_Click(object sender , EventArgs e)
        {
            _sType = ((Button)sender).Text;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Bitmap bmp = new Bitmap(pbImg.Width,pbImg.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.FillRectangle(new SolidBrush(pbImg.BackColor), new Rectangle(0, 0, pbImg.Width, pbImg.Height));//没有该句则绘制过程的痕迹也会显示出来
            g.Dispose();
            dt = new DrawTools(this.pbImg.CreateGraphics(), bmp);//实例化工具
        }
        private void pbImg_Paint(object sender,PaintEventArgs e)//解决窗体移动or最小化造成的pbImg重画
        {
            Graphics g = e.Graphics;
            g.DrawImage(dt.OrginalImg, 0, 0);
            //g.Dispose();不可使用!这个graphics是系统传入的变量,非我们创建,如果dispose就会出错;
        }
    }

    
}

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GDI_
{
    class DrawTools
    {
        public Graphics DrawTools_Graphics;
        private Pen p = new Pen(Color.Red,1);
        private Image orginalImg;    //原始画布,用于保存已完成的绘制过程
        public Image OrginalImg
        {
            set
            {
                finishingImg = (Image)value.Clone();
                orginalImg = (Image)value.Clone();
            }
            get 
            {
                return orginalImg;
            }
        }
        private Image finishingImg;  //中间画布,用于保存绘制过程中的痕迹
        private Graphics newgraphics;//中间画板
        public bool startDraw = false;//判断是否开始绘画
        public PointF startPointF;   //绘画起点
        /// <summary>
        /// 初始化绘图工具
        /// </summary>
        /// <param name="g">绘图板</param>
        /// <param name="img">初始画布</param>
        public DrawTools(Graphics g,Image img)
        {
            DrawTools_Graphics = g;
            Pen p = new Pen(Color.Red, 1);
            finishingImg = (Image)img.Clone();
            orginalImg = (Image)img.Clone();
        }
        public void Draw(MouseEventArgs e,string sType)
        {
            if(startDraw)
            {
                Image img = (Image)orginalImg.Clone();//为防止改写原始画布,我们定义了一个新的img来克隆原始画布
                newgraphics = Graphics.FromImage(img);//实例化中间画板
                switch(sType)
                {
                    case "Line": //直线
                        {
                            newgraphics.DrawLine(p, startPointF, new PointF(e.X, e.Y));break;
                        }
                    case "Ellipse"://画椭圆
                        {
                            newgraphics.DrawEllipse(p, startPointF.X, startPointF.Y, e.X - startPointF.X, e.Y - startPointF.Y);break;
                        }
                    case "Rectangle"://画矩形
                        {
                            float width = Math.Abs(e.X - startPointF.X);
                            float heigth = Math.Abs(e.Y - startPointF.Y);
                            PointF rectStartPointF = startPointF;
                            if(e.X < startPointF.X)
                            {
                                rectStartPointF.X = e.X;
                            }
                            if (e.Y < startPointF.Y)
                            {
                                rectStartPointF.Y = e.Y;
                            }
                            newgraphics.DrawRectangle(p,rectStartPointF.X, rectStartPointF.Y,width,heigth);
                            break;
                        }
                    case "Vertical"://画垂线
                        {
                            //暂且未查到能解决的资料
                            break;
                        }
                }
                newgraphics.Dispose();//绘制完毕释放中间画板所占资源
                newgraphics = Graphics.FromImage(finishingImg);//重新创建一个中间画板,画布为中间图片
                newgraphics.DrawImage(img, 0, 0);//将图片画到中间画板
                newgraphics.Dispose();
                DrawTools_Graphics.DrawImage(img, 0, 0);//将图片画到目标画板上
                img.Dispose();
            }
        }
        public void EndDraw()
        {
            startDraw = false;
            newgraphics = Graphics.FromImage(orginalImg);//为了让完成过后的绘图过程保留下来,要将中间图片绘制到原始画布上
            newgraphics.DrawImage(finishingImg, 0, 0);
            newgraphics.Dispose();
        }
    }
}

**注:**case “Vertical”:{//该代码每绘制完一次就将此时的画布作为下一次绘制的背景图片,这样就可以把以往的绘制结果以图片的形式保存下来。而画垂线需选中一条直线才行,可能需另寻他法。}
下表为Graphics类的常用方法

名称 说明
DrawARC 画圆弧
DrawBezier 画立体的贝尔塞曲线
DrawBeziers 画连续立体的贝尔塞曲线
DrawClosedCurve 画闭合曲线
DrawCurve 画曲线
DrawEllipse 画椭圆
DrawImage 画图像
DrawLine 画直线
DrawPath 通过路径画线和曲线
DrawPie 画饼形
DrawPolygon 画多边形
DrawRectangle 画矩形
DrawString 绘制文字
FillEllipse 填充椭圆
Fill’Path 填充路径
Fill’Pie 填充饼图
FillPolygon 填充多边形
FillRectangle 填充矩形
FillRectangles 填充矩形组
FillRegion 填充区域

**注:**在.NET中,GDI+的所有绘图功能都包括在System、System.Drawing、System.Drawing.Imaging、System.Drawing.Drawing2D、System.Drawing.Text等命名空间中,因此开始使用GDI+类之前,需要首先引用相应的命名空间。

相关标签: c# gdi/gdi+