Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
357 views
in Technique[技术] by (71.8m points)

c# - How can i cut drawn rectangle and display it in a pictureBox according to button click event?

What i want is that if i drawed a rectangle on one of the items in the pictureBox next time i click the button it will display those items when i click on them in the listBox only the rectangles i drawed.

This is what i tried so far:

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:	empSettings.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;

        }
    }
}

For the test i called the rectangle variable recttest. In the mouse up event i'm getting the rectangle i drawed in the current selected item in the listBox.

I can't upload here images but what i get is when i click the ConfirmRectangle button i see the the rectangle i drawed in the pictureBox the same as it was and the image in the pictureBox get resize get very very big from the inside like it was zoom in.

Instead what i wanted to get is the part of the image in the pictureBox that was marked/drawed by the rectangle. Like the rectangle is the border so when i click on the ConfirmRectangle i will see the part of the image was in the pictureBox in the rectangle and only this all the rest should not be shown.

I should see rectangle with inside the part of the image. Not to resize or zoom in the image only to cut the part was marked/drawn on by the rectangle.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

try following method.

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

Output

enter image description here

I am using ControPaint.DrawReversibleFrame method to draw rubber band. To read more about this method u can refere this tutorial


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...