如何根据按钮点击事件剪切绘制的矩形并将其显示在pictureBox中?

时间:2014-08-19 23:40:15

标签: c# .net winforms

我想要的是,如果我在下一次单击按钮时在pictureBox中的一个项目上绘制一个矩形,当我在listBox中单击它时,它将显示那些项目,而我只绘制了矩形。

这是我到目前为止所尝试的:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using DannyGeneral;
using System.Diagnostics;

namespace MinimizeCapture
{
    public partial class Form1 : Form
    {
        Point p1 = new Point(0, 0);
        Rectangle recttest;
        private Rectangle Rect;
        private Rectangle[] rectangles;
        private Rectangle RectClone;
        private bool btn = false;
        private Point RectStartPoint = Point.Empty;
        private Point RectEndPoint = Point.Empty;
        private Brush selectionBrush = new SolidBrush(Color.Red);
        private Pen pen;
        private string selectedIndex;
        private List<string> drawnItems = new List<string>();
        private bool ClearGraphics;

        public Form1()
        {
            InitializeComponent();


            var windows = OpenWindowGetter.FindWindowsWithText();
            ClearGraphics = false;
            this.DoubleBuffered = true;
            btn = false;
            pen = new Pen(selectionBrush);
            buttonSnap.Enabled = false;
            backgroundWorker1.RunWorkerAsync();
        }

        private void buttonSnap_Click(object sender, EventArgs e)
        {
            ClearGraphics = true;
            this.listBoxSnap.Items.Clear();
            this.pictureBoxSnap.Image = null;
            backgroundWorker1.RunWorkerAsync();
        }

        private void CutRectangle()
        {
            for (int i = 0; i < rectangles.Length; i++)
            {
                if (!rectangles[i].IsEmpty)
                {

                }
            }
        }

        private void listBoxSnap_SelectedIndexChanged(object sender, EventArgs e)
        {

            WindowSnap snap = this.listBoxSnap.SelectedItem as WindowSnap;
            selectedIndex = this.listBoxSnap.SelectedIndex.ToString();
            this.pictureBoxSnap.Image = snap.Image;
            for (int i = 0; i < rectangles.Length; i++)
            {
                if (rectangles[i] != RectClone)
                {
                    ClearGraphics = false;
                }
                else
                {
                    ClearGraphics = true;
                }
            }

        }

        private void checkBoxForceMDI_CheckedChanged(object sender, EventArgs e)
        {
            WindowSnap.ForceMDICapturing = (sender as CheckBox).Checked;
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.Add("Minimized Windows"); }));
            listBoxSnap.Invoke(new MethodInvoker(delegate { this.listBoxSnap.Items.AddRange(WindowSnap.GetAllWindows(true,true).ToArray()); }));
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            rectangles = new Rectangle[listBoxSnap.Items.Count];
            buttonSnap.Enabled = true;
        }

        private void pictureBoxSnap_Paint(object sender, PaintEventArgs e)
        {

            if (pictureBoxSnap.Image != null)
            {
                {
                    if (ClearGraphics == false)
                    {
                        if (rectangles[listBoxSnap.SelectedIndex] != Rectangle.Empty)
                        {
                            e.Graphics.DrawRectangle(Pens.Firebrick, rectangles[listBoxSnap.SelectedIndex]);
                        }
                        if (recttest.Width > 10 && recttest.Height > 10)
                            e.Graphics.DrawRectangle(Pens.Firebrick, recttest);
                    }
                }
            }           
        }

        private void pictureBoxSnap_MouseMove(object sender, MouseEventArgs e)
        {

            if (btn == true)
            {
                ClearGraphics = false;
                RectEndPoint = e.Location;
                int currentindex = listBoxSnap.SelectedIndex;
                rectangles[currentindex] = RectClone;
                Rect = getRect(RectStartPoint, RectEndPoint);
                RectClone = Rect;
                pictureBoxSnap.Invalidate();
            }
        }

        private void pictureBoxSnap_MouseDown(object sender, MouseEventArgs e)
        {
            RectStartPoint = e.Location;
            btn = true;
            Rect = Rectangle.Empty;
            RectClone = Rectangle.Empty;
            p1 = e.Location;
        }

        private void pictureBoxSnap_MouseUp(object sender, MouseEventArgs e)
        {
            recttest = rectangles[listBoxSnap.SelectedIndex];
            ClearGraphics = false;
            btn = false;
            RectEndPoint = e.Location;
            pictureBoxSnap.Invalidate();
            int currentindex = listBoxSnap.SelectedIndex;
            rectangles[currentindex] = RectClone;

            if (e.Location.X > p1.X)
            {
                recttest.X = p1.X;
                recttest.Width = e.Location.X - p1.X;
            }
            else
            {
                recttest.X = e.Location.X;
                recttest.Width = p1.X - e.Location.X;
            }

            //Top and Height
            if (e.Location.Y > p1.Y)
            {
                recttest.Y = p1.Y;
                recttest.Height = e.Location.Y - p1.Y;
            }
            else
            {
                recttest.Y = e.Location.Y;
                recttest.Height = p1.Y - e.Location.Y;
            }
            if (recttest.Width > 10 && recttest.Height > 10)
                pictureBoxSnap.Invalidate();
        }

        Rectangle getRect(Point p1, Point p2)
        {
            Point p = new Point(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y));
            Size s = new Size(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
            return new Rectangle(p, s);
        }

        private void ConfirmRectangle_Click(object sender, EventArgs e)
        {
            ConfirmRectangle.ForeColor = Color.Red;
            ConfirmRectangle.Enabled = false;
            StreamWriter w = new StreamWriter(@"c:\temp\Settings.txt", true);
            w.WriteLine("Rectangle Location: " + RectClone.Location + " Rectangle Size: " + RectClone.Size + " Selected Index: " + selectedIndex);
            textBoxIndex.Text = selectedIndex.ToString();
            w.Close();
            pictureBoxSnap.Image = CropImage();
        }

        private Bitmap CropImage()
        {
            Bitmap pic = pictureBoxSnap.Image as Bitmap;
            Bitmap cropped = new Bitmap(recttest.Width, recttest.Height);

            using (Graphics g = Graphics.FromImage(cropped))
            {
                g.DrawImage(pic, new Rectangle(0, 0, recttest.Width, recttest.Height),
                             recttest, GraphicsUnit.Pixel);
            }
            return cropped;

        }
    }
}

对于测试我称为矩形变量recttest。 在鼠标注册事件中,我得到了在listBox中当前所选项目中绘制的矩形。

我无法在这里上传图片,但我得到的是当我点击ConfirmRectangle按钮时,我看到我在pictureBox中绘制的矩形与它相同,而且在PictureBox中获取调整大小的图像从中获取非常大的里面就像放大了一样。

相反,我想得到的是pictureBox中由矩形标记/绘制的图像部分。就像矩形是边框所以当我点击ConfirmRectangle时,我会看到图像的一部分位于矩形的pictureBox中,只有这一部分不应该显示。

我应该在图像的一部分内部看到矩形。不调整大小或放大图像只是为了切割零件被矩形标记/绘制。

1 个答案:

答案 0 :(得分:0)

尝试以下方法。

    Boolean bHaveMouse;
    Point ptOriginal = new Point();
    Point ptLast = new Point();

    private void pictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        bHaveMouse = true;
        // Store the "starting point" for this rubber-band rectangle.
        ptOriginal.X = e.X;
        ptOriginal.Y = e.Y;
        // Special value lets us know that no previous
        // rectangle needs to be erased.
        ptLast.X = -1;
        ptLast.Y = -1;
    }

    // Convert and normalize the points and draw the reversible frame.
    private void MyDrawReversibleRectangle(Point p1, Point p2)
    {
        Rectangle rc = new Rectangle();

        // Convert the points to screen coordinates.
        p1 = pictureBox.PointToScreen(p1);
        p2 = pictureBox.PointToScreen(p2);
        // Normalize the rectangle.
        if (p1.X < p2.X)
        {
            rc.X = p1.X;
            rc.Width = p2.X - p1.X;
        }
        else
        {
            rc.X = p2.X;
            rc.Width = p1.X - p2.X;
        }
        if (p1.Y < p2.Y)
        {
            rc.Y = p1.Y;
            rc.Height = p2.Y - p1.Y;
        }
        else
        {
            rc.Y = p2.Y;
            rc.Height = p1.Y - p2.Y;
        }
        // Draw the reversible frame.
        rect = new Rectangle(pictureBox.PointToClient(rc.Location), rc.Size);
        ControlPaint.DrawReversibleFrame(rc, Color.Gray, FrameStyle.Dashed);
    }

    Rectangle rect = Rectangle.Empty;

    private void pictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        // Set internal flag to know we no longer "have the mouse".
        bHaveMouse = false;
        // If we have drawn previously, draw again in that spot
        // to remove the lines.
        if (ptLast.X != -1)
        {
            Point ptCurrent = new Point(e.X, e.Y);
            MyDrawReversibleRectangle(ptOriginal, ptLast);
        }
        // Set flags to know that there is no "previous" line to reverse.
        ptLast.X = -1;
        ptLast.Y = -1;
        ptOriginal.X = -1;
        ptOriginal.Y = -1;
        pictureBox.Invalidate();
    }

    private void pictureBox_Paint(object sender, PaintEventArgs e)
    {
        if (rect.Width > 10 && rect.Height > 10)
        {
            e.Graphics.DrawRectangle(Pens.Gray, rect);
            pictureBox1.Image =  CropImage();
        }
    }

    private Bitmap CropImage()
    {
        Bitmap pic = pictureBox.Image as Bitmap;
        Bitmap cropped = new Bitmap(rect.Width, rect.Height);

        using (Graphics g = Graphics.FromImage(cropped))
        {
            g.DrawImage(pic, new Rectangle(0, 0, rect.Width, rect.Height),
                         rect, GraphicsUnit.Pixel);
        }
        return cropped;

    }

    private void pictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        Point ptCurrent = new Point(e.X, e.Y);
        // If we "have the mouse", then we draw our lines.
        if (bHaveMouse)
        {
            // If we have drawn previously, draw again in
            // that spot to remove the lines.
            if (ptLast.X != -1)
            {
                MyDrawReversibleRectangle(ptOriginal, ptLast);
            }
            // Update last point.
            ptLast = ptCurrent;
            // Draw new lines.
            MyDrawReversibleRectangle(ptOriginal, ptCurrent);
        }
    }

<强>输出

enter image description here

我正在使用ControPaint.DrawReversibleFrame方法绘制橡皮筋。要了解有关此方法的更多信息,请参阅此tutorial