如何在不清除原始图像的情况下清除pictureBox1中的所有绘制图形?

时间:2014-09-23 19:38:56

标签: c# .net winforms

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;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace mws
{
    public partial class ColorClouds : Form
    {
        private Bitmap _bmpBU = null;
        private Rectangle mRect;

        public ColorClouds()
        {
            InitializeComponent();

            this.DoubleBuffered = true;
            _bmpBU = new Bitmap(@"D:\MyWeatherStation-Images-And-Icons\radar090.PNG");
        }

        private void ColorClouds_Load(object sender, EventArgs e)
        {
            this.pictureBox1.Image = (Bitmap)_bmpBU.Clone();
            this.pictureBox2.Image = (Bitmap)_bmpBU.Clone();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                ScanBmpFast((Bitmap)this.pictureBox1.Image, true, new Rectangle(40, 10, 20, 50));
                this.pictureBox1.Refresh();
            }
        }

        private unsafe void ScanBmpFast(Bitmap bmp, bool setToOpaqueYellow, Rectangle rect)
        {
            BitmapData b1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            int stride = b1.Stride;
            int nWidth = bmp.Width;
            int nHeight = bmp.Height;

            System.IntPtr Scan0 = b1.Scan0;

            byte* p = (byte*)(void*)Scan0;

            int sX = Math.Min(Math.Max(rect.X, 0), bmp.Width);
            int sY = Math.Min(Math.Max(rect.Y, 0), bmp.Height);
            int w = Math.Min(rect.Width, bmp.Width - sX);
            int h = Math.Min(rect.Height, bmp.Height - sY);

            for (int y = sY; y < sY + h; y++)
            {
                p = (byte*)(void*)Scan0;
                p += (y * stride + sX * 4);

                for (int x = sX; x < sX + w; x++)
                {
                    if (p[0] != 0 || p[1] != 0 || p[2] != 0)
                    {
                        p[1] = p[2] = (byte)255;

                        if (setToOpaqueYellow)
                        {
                            p[0] = (byte)0;
                            p[3] = (byte)255;
                        }
                    }

                    p += 4;
                }
            }

            bmp.UnlockBits(b1);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (pictureBox2.Image != null)
            {
                ScanBmp((Bitmap)this.pictureBox2.Image, true, new Rectangle(400, 100, 200, 500));
                this.pictureBox2.Refresh();
            }
        }

        private void ScanBmp(Bitmap bmp, bool setToOpaqueYellow, Rectangle rect)
        {
            BitmapData b1 = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            int stride = b1.Stride;
            int nWidth = bmp.Width;
            int nHeight = bmp.Height;

            System.IntPtr Scan0 = b1.Scan0;
            IntPtr p = b1.Scan0;

            int sX = Math.Min(Math.Max(rect.X, 0), bmp.Width);
            int sY = Math.Min(Math.Max(rect.Y, 0), bmp.Height);
            int w = Math.Min(rect.Width, bmp.Width - sX);
            int h = Math.Min(rect.Height, bmp.Height - sY);

            for (int y = sY; y < sY + h; y++)
            {
                p = Scan0;
                p += y * stride + sX * 4;

                for (int x = sX; x < sX + w; x++)
                {

                    if (Marshal.ReadByte(p) != 0 || Marshal.ReadByte(p + 1) != 0 || Marshal.ReadByte(p + 2) != 0)
                    {
                        byte res = (byte)255;
                        Marshal.WriteByte(p + 1, res);
                        Marshal.WriteByte(p + 2, res);

                        if (setToOpaqueYellow)
                        {
                            Marshal.WriteByte(p, (byte)0);
                            Marshal.WriteByte(p + 2, (byte)255);
                        }
                    }

                    p += 4;
                }
            }

            bmp.UnlockBits(b1);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Image iOLd = this.pictureBox1.Image;
            this.pictureBox1.Image = (Bitmap)_bmpBU.Clone();
            if (iOLd != null)
                iOLd.Dispose();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            Image iOLd = this.pictureBox2.Image;
            this.pictureBox2.Image = _bmpBU;
            if (iOLd != null)
                iOLd.Dispose();
        }

        private void ColorClouds_FormClosing(object sender, FormClosingEventArgs e)
        {
            Image iOLd = this.pictureBox1.Image;
            this.pictureBox1.Image = (Bitmap)_bmpBU.Clone();
            if (iOLd != null)
                iOLd.Dispose();
            iOLd = this.pictureBox2.Image;
            this.pictureBox2.Image = _bmpBU;
            if (iOLd != null)
                iOLd.Dispose();

            if (_bmpBU != null)
                _bmpBU.Dispose();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawRectangle(pen, mRect);
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mRect = new Rectangle(mRect.Left, mRect.Top, e.X - mRect.Left, e.Y - mRect.Top);
                pictureBox1.Invalidate();
            }
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            mRect = new Rectangle(e.X, e.Y, 0, 0);
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image != null)
            {
                ScanBmpFast((Bitmap)this.pictureBox1.Image, true, mRect);
                this.pictureBox1.Refresh();
            }
        }
    }
}

我这样做我可以在picturebox1上绘制矩形并用矩形填充它。 当我点击pictureBox1再次绘制时,矩形框架是清晰的,但在矩形内部绘制它不是。

ScanBmpFast只填充我用某种颜色绘制的矩形。 这种颜色没有清除。只有矩形框架。 我想清除所有内容,只留下原始图像。

1 个答案:

答案 0 :(得分:0)

叹息。如果您不在Paint(直接或在其可能传递的e.Graphics上),事件将不会持续存在。

所以你需要做的就是去除那些非持久性像素,就是调用

pictureBox1.Invalidate();

这当然导致了这个问题,你在画什么,为什么不做你做对的?在Paint事件之外抽取的任何内容不仅会被Invalidate()您的代码调用删除,还会被许多外部事件删除,例如最小化Form等。

持续绘图(除非你绘制到Image)将需要创建数据结构,其中包含绘制内容和方式的详细信息,即Points, Rectangles, Brushes, Pens等。

要删除这种持久性绘图,请清除这些数据..

因此,如果您不希望在Rectangle活动中绘制Paint,请不要这样做!只要你有代码,它就会重新出现。