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

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+类之前,需要首先引用相应的命名空间。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值