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

时间:2015-01-02 18:21:25

标签: c# winforms

我一直在尝试编写程序,能够在表单上加载图像并在其上选择一个矩形,然后将该矩形加载到另一个图片框(pictureBox2)上,我也希望能够突出显示我在原始图片上选择的内容,在pictureBox1中,当我移动鼠标时。

到目前为止,我有这段代码,但它没有正确响应mouseMove事件,我突出显示的矩形没有正确选择。有什么问题?

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();
    }
}

1 个答案:

答案 0 :(得分:1)

我认为您的问题是“原始”图片尺寸与图片框尺寸不同。尝试使用此代码来补偿“原始”图像与图片框大小之间的缩放比例:

            // 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
                    );
            }

这修复了我的情况下的红色矩形。但是picturebox2中复制的部分仍然不正确......

这会将副本修复到第二个图片框:

            // 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);
            }