2 niugongni4046 niugongni4046 于 2017.01.10 19:17 提问

简单的一个画图程序,一画图就报错

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
Bitmap bmpOrigin;
Pen pen;
Brush brush;
Point ptOld;
Font ftString;
ArrayList arrCurvePoint = new ArrayList();//画曲线
ArrayList arrPolygonPoint = new ArrayList();//画多边形

    public Form1()
    {

        InitializeComponent();
    }



    private void Form1_Load_1(object sender, EventArgs e)
    {

    }

    private void picBox_MouseDown(object sender, MouseEventArgs e)
    {
        pen = new Pen(pnlForeColor.BackColor, (float)udLineSize.Value);
        switch (cmbLineShape.SelectedIndex)//处理画笔
        {
            case 0: pen.DashStyle = DashStyle.Solid; break;//实线
            case 1: pen.DashStyle = DashStyle.Dash; break;//虚线
            case 2: pen.DashStyle = DashStyle.Dot; break;//点线
            case 3: pen.DashStyle = DashStyle.DashDot; break;//点划线
            case 4: pen.DashStyle = DashStyle.DashDotDot; break;//双点划线

        }
        switch (cmbFillDesign.SelectedIndex)//处理笔刷
        {
            case 0: brush = null; break;
            case 1: brush = new SolidBrush(pnlBackColor.BackColor); break;
        }
        if (rdbCurve.Checked || rdbErase.Checked)
        {
            arrCurvePoint.Clear();//清除里面的点
            arrCurvePoint.Add(e.Location);//把鼠标当前位置作为第一个点
        }
        //多边形
        if (rdbPolygon.Checked && arrPolygonPoint.Count == 0)
        {
            arrPolygonPoint.Add(e.Location);
        }
        ptOld = e.Location;
    }
    private void ControlResize(MouseEventArgs mouse)//自定义函数用来改变画幅的大小
    {
        if (mouse.Button != MouseButtons.Left)//不是单击左键
        {
            if (mouse.X >= picBox.Width - 4)
                picBox.Cursor = Cursors.VSplit;
            else if (mouse.Y >= picBox.Height - 4)
                picBox.Cursor = Cursors.HSplit;
            else
                picBox.Cursor = Cursors.Cross;
        }
        else//按了左键并移动
        {
            if (picBox.Cursor == Cursors.VSplit && mouse.X > 20)//超出范围改变画框
            {
                picBox.Width = mouse.X;
            }
            if (picBox.Cursor == Cursors.HSplit && mouse.Y > 20)
            {
                picBox.Height = mouse.Y;
            }
            if (picBox.Cursor != Cursors.Cross && picBox.Image != null)//这一系列操作完成了改变图片框的尺寸,并同步bmpOrigin的大小,并把picBox的图片重新画到bmpOrigin里。
            {
                bmpOrigin = new Bitmap(picBox.Width, picBox.Height);
                if (picBox.Image != null)
                {
                    Graphics gOrigin = Graphics.FromImage(bmpOrigin);
                    gOrigin.DrawImage(picBox.Image, 0, 0);
                }
                picBox.Image = bmpOrigin;
            }

        }



    }

    private void picBox_MouseMove(object sender, MouseEventArgs e)
    {
        ControlResize(e);
        if (e.Button == MouseButtons.Left && picBox.Cursor == Cursors.Cross)
        {
            Bitmap bmpTemp = (Bitmap)bmpOrigin.Clone();
            Graphics gTemp = Graphics.FromImage(bmpTemp);
            if (rdbLine.Checked)//画直线
            {
                gTemp.DrawLine(pen, ptOld, e.Location);

            }
            else if (rdbRectangl.Checked)//画矩形
            {
                float x = (ptOld.X < e.X) ? ptOld.X : e.X;//三目运算符,如果当前鼠标位置>起始点
                float y = (ptOld.Y < e.Y) ? ptOld.Y : e.Y;
                gTemp.DrawRectangle(pen, x, y, Math.Abs(e.X - ptOld.X), Math.Abs(e.Y - ptOld.Y));
                if (brush != null)
                    gTemp.FillRectangle(brush, x, y, Math.Abs(e.X - ptOld.X), Math.Abs(e.Y - ptOld.Y));
            }
            else if (rdbEllipse.Checked)//画椭圆
            {
                float x = (ptOld.X < e.X) ? ptOld.X : e.X;//三目运算符,如果当前鼠标位置>起始点
                float y = (ptOld.Y < e.Y) ? ptOld.Y : e.Y;
                gTemp.DrawEllipse(pen, x, y, Math.Abs(e.X - ptOld.X), Math.Abs(e.Y - ptOld.Y));
                if (brush != null)
                    gTemp.FillEllipse(brush, x, y, Math.Abs(e.X - ptOld.X), Math.Abs(e.Y - ptOld.Y));
            }
            else if (rdbCurve.Checked)//画曲线
            {
                Graphics gOrigin = Graphics.FromImage(bmpOrigin);
                arrCurvePoint.Add(e.Location);
                Point[] p = new Point[arrCurvePoint.Count];
                arrCurvePoint.CopyTo(p);
                gOrigin.DrawCurve(pen, p);
                picBox.Image = bmpOrigin;
            }
            else if (rdbErase.Checked)//橡皮擦
            {
                Graphics gOrigin = Graphics.FromImage(bmpOrigin);
                arrCurvePoint.Add(e.Location);
                Point[] p = new Point[arrCurvePoint.Count];
                arrCurvePoint.CopyTo(p);
                gOrigin.DrawCurve(new Pen(pnlBackColor.BackColor, (float)udLineSize.Value), p);
                picBox.Image = bmpOrigin;

            }
            else if (rdbPolygon.Checked && arrPolygonPoint.Count > 0)//多边形(一定要结合mouseup代码结合起来看
            {

                gTemp.DrawLine(pen, (Point)arrPolygonPoint[arrPolygonPoint.Count - 1], e.Location);

            }
            else if (rdbText.Checked)//处理文本要看三个地方:1.mouseDown事件里确定第一个点的位置  2.from_load里有 ftString实例化操作 3.就是下面的代码确定文本框的大小
            {
                txtString.Width = e.X - ptOld.X;
                txtString.Height = e.Y - ptOld.Y;
                txtString.Focus();

            }
            picBox.Image = bmpTemp;
        }


    }

    private void picBox_MouseUp(object sender, MouseEventArgs e)
    {
        if (picBox.Image != null)
        {
            Graphics gp = Graphics.FromImage(bmpOrigin);
            gp.DrawImage(picBox.Image, 0, 0);

        }

        //画多边形时除将第1个点外的所有点添加到arrPolygonPoin数组中
        if (arrPolygonPoint.Count > 0)
            arrPolygonPoint.Add(e.Location);
    }

    private void picBox_MouseDoubleClick(object sender, MouseEventArgs e)
    {
        if (rdbPolygon.Checked)
        {
            Graphics gOrigin = Graphics.FromImage(bmpOrigin);
            Point[] p = new Point[arrPolygonPoint.Count];
            arrPolygonPoint.CopyTo(p);
            gOrigin.DrawPolygon(pen, p);
            arrPolygonPoint.Clear();
            if (brush != null)
            {
                gOrigin.FillPolygon(brush, p);
            }
            gOrigin.Dispose();
            picBox.Image = bmpOrigin;
        }
    }

    private void pnlForeColor_Paint(object sender, PaintEventArgs e)
    {
        ColorDialog cd = new ColorDialog();
        cd.Color = pnlForeColor.BackColor;
        DialogResult dr = cd.ShowDialog();
        if (dr == DialogResult.OK)
            pnlForeColor.BackColor = cd.Color;
    }

    private void pnlBackColor_Paint(object sender, PaintEventArgs e)
    {
        ColorDialog cd = new ColorDialog();
        cd.Color = pnlBackColor.BackColor;
        DialogResult dr = cd.ShowDialog();
        if (dr == DialogResult.OK)
            pnlBackColor.BackColor = cd.Color;
    }

    private void picBox_MouseClick(object sender, MouseEventArgs e)
    {
        if (rdbGetColor.Checked)
        {
            if (bmpOrigin.GetPixel(e.X, e.Y).ToArgb() != 0)
            {
                if (e.Button == MouseButtons.Left)
                {
                    pnlForeColor.BackColor = bmpOrigin.GetPixel(e.X, e.Y);
                }
                else
                {
                    pnlBackColor.BackColor = bmpOrigin.GetPixel(e.X, e.Y);
                }
            }
            else
            {
                if (e.Button == MouseButtons.Left)
                {
                    pnlForeColor.BackColor = picBox.BackColor;
                }
                else
                {
                    pnlBackColor.BackColor = picBox.BackColor;
                }
            }
        }
    }
}

}
图片说明

1个回答

Tiger_Zhao
Tiger_Zhao   Rxr 2017.01.12 16:06
    private void picBox_MouseMove(object sender, MouseEventArgs e)
    {
        ControlResize(e);
        if (e.Button == MouseButtons.Left && picBox.Cursor == Cursors.Cross)
            Bitmap bmpTemp = (Bitmap)bmpOrigin.Clone();

ControlResize() 中设为 Cursors.Cross 是不创建 bmpOrigin 对象正好是两个分支。
所有 bmpOrigin 对象为空的时候进入 if 分支调用 bmpOrigin.Clone()
这是什么逻辑?

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!