简体   繁体   English

如何在C#中的图片框内正确选择图像的特定部分并将其突出显示?

[英]How do I properly select a certain part of an image inside a picture box in C# and highlight it?

I have been trying to write a program, to be able to load an image on a form and select a rectangle on it, then load that rectangle onto another picture box (pictureBox2), and I also want to be able to highlight what I have selected on the original picture, in pictureBox1, as I move my mouse. 我一直在尝试编写一个程序,以便能够在窗体上加载图像并选择一个矩形,然后将该矩形加载到另一个图片框(pictureBox2)上,并且我还想突出显示我拥有的内容当我移动鼠标时,在原始图片上的pictureBox1中选择。

So far I have this code, but it doesn't properly respond to the mouseMove event, the rectangle that I highlight isn't selected properly. 到目前为止,我已经有了这段代码,但是它无法正确响应mouseMove事件,没有正确选择我突出显示的矩形。 What is the problem? 问题是什么?

public partial class Form1 : Form
{
    Bitmap original;
    bool isSelecting;
    int x0, y0, x1, y1;
    public Form1()
    {
        InitializeComponent();
        pictureBox1.MouseDown += new MouseEventHandler(picOriginal_MouseDown);
        pictureBox1.MouseMove += new MouseEventHandler(picOriginal_MouseMove);
        pictureBox1.MouseUp   += new MouseEventHandler(picOriginal_MouseUp);
    }

    #region helpder methods

    // Start selecting the rectangle.
    private void picOriginal_MouseDown(object sender, MouseEventArgs e)
    {
        if(original != null)
        {
            isSelecting = true;
            // Save the start point.
            x0 = e.X;
            y0 = e.Y;
        }
    }

    // Continue selecting.
    private void picOriginal_MouseMove(object sender, MouseEventArgs e)
    {
        if(original != null)
        {
            // Do nothing it we're not selecting an area.
            if(!isSelecting) return;

            // Save the new point.
            x1 = e.X;
            y1 = e.Y;

            // Make a Bitmap to display the selection rectangle.
            Bitmap bm = new Bitmap(original);

            // Draw the rectangle.
            using(Graphics gr = Graphics.FromImage(bm))
            {
                gr.DrawRectangle(Pens.Red,
                    Math.Min(x0, x1), Math.Min(y0, y1),
                    Math.Abs(x0 - x1), Math.Abs(y0 - y1)
                    );
            }

            // Display the temporary bitmap.
            pictureBox1.Image = new Bitmap(bm, new Size(pictureBox1.Width, pictureBox1.Height));
        }
    }

    // Finish selecting the area.
    private void picOriginal_MouseUp(object sender, MouseEventArgs e)
    {
        if(original != null)
        {
            // Do nothing it we're not selecting an area.
            if(!isSelecting) return;
            isSelecting = false;

            // Display the original image.
            pictureBox1.Image = original;

            // Copy the selected part of the image.
            int wid = Math.Abs(x0 - x1);
            int hgt = Math.Abs(y0 - y1);
            if((wid < 1) || (hgt < 1)) return;

            Bitmap area = new Bitmap(wid, hgt);
            using(Graphics gr = Graphics.FromImage(area))
            {
                Rectangle source_rectangle =
                    new Rectangle(Math.Min(x0, x1), Math.Min(y0, y1),
                        wid, hgt);
                Rectangle dest_rectangle =
                    new Rectangle(0, 0, wid, hgt);
                gr.DrawImage(original, dest_rectangle,
                    source_rectangle, GraphicsUnit.Pixel);
            }

            // Display the result.
            pictureBox2.Image = area;
        }
    }

    #endregion

    private void button1_Click(object sender, EventArgs e)
    {
        if(original != null)
        {

        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        OpenFileDialog dialog = new OpenFileDialog();
        dialog.Filter = "jpg files (*.jpg)|*.jpg|All files(*.*)|*.*";
        if(dialog.ShowDialog() == DialogResult.OK)
        {
            original = new Bitmap(dialog.FileName);
            pictureBox1.Image = new Bitmap(original, new Size(pictureBox1.Width,     pictureBox1.Height));
        }
        dialog.Dispose();
    }
}

I think your problem is the 'original' image size which is not the same as the picturebox size. 我认为您的问题是“原始”图像尺寸与图片框尺寸不同。 Try this code to compensate for the zoom ratio between your 'original' image and the picturebox size: 尝试使用以下代码来补偿“原始”图像和图片框尺寸之间的缩放比例:

            // Draw the rectangle.
            float zoomX = (float)original.Size.Width / pictureBox1.Width;
            float zoomY = (float)original.Size.Height / pictureBox1.Height;

            using (Graphics gr = Graphics.FromImage(bm))
            {
                gr.DrawRectangle(Pens.Red,
                    Math.Min(x0, x1) * zoomX, Math.Min(y0, y1) * zoomY,
                    Math.Abs(x0 - x1) * zoomX, Math.Abs(y0 - y1) * zoomY
                    );
            }

This fixes the red rectangle in my case. 在我的情况下,这可以修复红色矩形。 But the copied part in picturebox2 is still not correct... 但是picturebox2中复制的部分仍然不正确...

And this fixes the copy to the second picturebox: 这会将副本固定到第二个图片框:

            // Copy the selected part of the image.
            float zoomX = (float)original.Size.Width / pictureBox1.Width;
            float zoomY = (float)original.Size.Height / pictureBox1.Height;
            int wid = (int)(zoomX * Math.Abs(x0 - x1));
            int hgt = (int)(zoomY * Math.Abs(y0 - y1));
            if ((wid < 1) || (hgt < 1)) return;

            Bitmap area = new Bitmap(wid, hgt);
            using (Graphics gr = Graphics.FromImage(area))
            {
                Rectangle source_rectangle =
                    new Rectangle((int)(zoomX * Math.Min(x0, x1)), (int)(zoomY * Math.Min(y0, y1)),
                        wid, hgt);
                Rectangle dest_rectangle =
                    new Rectangle(0, 0, wid, hgt);
                gr.DrawImage(original, dest_rectangle,
                    source_rectangle, GraphicsUnit.Pixel);
            }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM