【问题标题】:How to draw multiple rectangles with mouse on an image?如何用鼠标在图像上绘制多个矩形?
【发布时间】:2014-06-06 14:47:27
【问题描述】:

我正在尝试构建一个 WinForm 应用程序,该应用程序将从 openfiledialog 加载图像文件并将其加载到面板或图片框中。我希望能够用鼠标左键绘制多个矩形并将它们留在图像上。我已经成功地在实际表单上一次获得一个矩形,但在面板/图片框内的图像上却没有。有谁知道可以帮助我了解如何实现这一目标的资源?

这是允许我在表单上绘制单个可调整大小的矩形的代码,但是当我将鼠标事件从 form1_MouseEvent 更改为 panel1_MouseEvent 时,它什么也不做......

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 Temporary_Name_Utility
{
    public partial class Form1 : Form
    {
        Rectangle myRectangle;
        bool draw = false;


        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog myFile = new OpenFileDialog();
                myFile.Filter = "Image Files(*.img, *.bmp) |*.img; *.bmp;";
                myFile.InitialDirectory = "c:\\";

                if (myFile.ShowDialog() == DialogResult.OK)
                {
                    pictureBox1.BackgroundImage = Image.FromFile(myFile.FileName);
                }
            }

            catch (Exception error)
            {
                MessageBox.Show("Error loading the selected file.  Original error: " + error.Message);

            }

        }

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


        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if(draw)
            {
                using(Pen myPen = new Pen(Color.Red, 2))
                {
                    e.Graphics.DrawRectangle(myPen, myRectangle);
                }
            }
        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left)
            {
                myRectangle = new Rectangle(myRectangle.Left, myRectangle.Top, Math.Min(e.X - myRectangle.Left, pictureBox1.ClientRectangle.Width - myRectangle.Left), Math.Min(e.Y - myRectangle.Top, pictureBox1.ClientRectangle.Height - myRectangle.Top));
            }
            this.Invalidate();
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {

        }

    }
}

【问题讨论】:

  • 显示您已有的代码。当前形式的问题是题外话。
  • @LarsTech,怎么跑题了?我要求有人建议/指向我的资源,以帮助我了解如何实现这一目标..
  • google 搜索“how to draw on picturebox c#”怎么样?我认为第一个结果就是您要寻找的结果。
  • @Renius,请不要认为这很粗鲁,但是来吧..你认为我没有先尝试谷歌吗?我一直在谷歌上找到的东西并没有给我我需要的帮助,这就是为什么我转向 SO 看看是否有人知道文章/博客/等很容易在结果中被阻止或通过搜索错误的关键字来查看..
  • 我没有看到绘画事件。

标签: c# winforms openfiledialog


【解决方案1】:

终于得到了一些工作代码:这允许用户在图片框内用鼠标绘制任意数量的矩形。

     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 Rectangle_Utility
{
    public partial class Form1 : Form
    {
        Point startPos;
        Point currentPos;
        bool drawing;
        List<Rectangle> myRectangles = new List<Rectangle>();

        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
        }

        #region Menu Tool Strip
        private void selectFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                //Initiate new OpenFileDialog
                //Filter for img and bmp files
                //Start looking in root of c:
                OpenFileDialog myFile = new OpenFileDialog();
                myFile.Filter = "Image Files(*.img, *.bmp) |*.img; *.bmp;";
                myFile.InitialDirectory = "c:\\";

                //Set background image of pictureBox to file selected through OpenFileDialog
                if (myFile.ShowDialog() == DialogResult.OK)
                {
                    pictureBox1.BackgroundImage = Image.FromFile(myFile.FileName);

                }
            }

            catch (Exception error)
            {
                MessageBox.Show("Error loading the selected file.  Original error: " + error.Message);

            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void clearAllToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void zoomToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void undoLastActionToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void redoLastActionToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        #endregion

        #region Rectangle

        private Rectangle getRectangle()
        {
            return new Rectangle(
                Math.Min(startPos.X, currentPos.X),
                Math.Min(startPos.Y, currentPos.Y),
                Math.Abs(startPos.X - currentPos.X),
                Math.Abs(startPos.Y - currentPos.Y));
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                currentPos = startPos = e.Location;
                drawing = true;
            }

        }

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            currentPos = e.Location;
            if (drawing) pictureBox1.Invalidate();
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            if (myRectangles.Count > 0) e.Graphics.DrawRectangles(Pens.Black, myRectangles.ToArray());
            if (drawing) e.Graphics.DrawRectangle(Pens.Red, getRectangle());
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            if (drawing)
            {
                drawing = false;
                var rect = getRectangle();
                if (rect.Width > 0 && rect.Height > 0) myRectangles.Add(rect);
                pictureBox1.Invalidate();
            }
        }

        #endregion

    }
}

【讨论】:

    【解决方案2】:

    您必须从图像创建一个图形并使用该图形绘制矩形,以便在图像中绘制矩形。

    Graphics newGraphics = Graphics.FromImage(image);
    newGraphics.FillRectangle(new SolidBrush(Color.Black), rectangles);
    

    【讨论】:

    • 不要忘记在使用完图形实例后调用 .Dispose(),否则会泄漏 GDI 句柄,直到垃圾收集器开始清理您的实例。
    • 这会创建一个独立的内存Graphics 对象,在其中绘制一个矩形,然后将其丢弃。它不会影响屏幕或 WinForm 应用程序。
    猜你喜欢
    • 2023-01-03
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    相关资源
    最近更新 更多