Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing reversible rectangle

Tags:

c#

I got code from http://support.microsoft.com/kb/314945 to draw a reversible/rubber band rectangle. I added code to it so that when i leave the left mouse button a rectangle is also created on the image and then i use that for cropping the image.

This works superb. the only problem is that the rubberband rectangle doesnot start or end from where the mouse is... there is very little diference but still it is quite notable. i use the same co-ords to draw the rectangle afterwards which is drawn exactly where my mouse started and where is ended. help would be appreciated.

Here is the code: (Got issue fixed - adding code that others can benefit from it) I have made it a control and i use it wherever i need it!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CroppingControl
{
    public partial class CroppingImage : UserControl
    {
        Rectangle rc = new Rectangle();
        Boolean bHaveMouse;
        Point ptOriginal = new Point();
        Point ptLast = new Point();
        Image Pic;

        public CroppingImage()
        {
            InitializeComponent();
            pictureBox1.MouseDown += new MouseEventHandler(MyMouseDown);
            pictureBox1.MouseUp += new MouseEventHandler(MyMouseUp);
            pictureBox1.MouseMove += new MouseEventHandler(MyMouseMove);
            bHaveMouse = false;
        }


        public Image Image
        {
            set
            {
                pictureBox1.Image = value;
                Pic = value;
            }
            get
            {
                return pictureBox1.Image;
            }
        }

        public void MyMouseDown(Object sender, MouseEventArgs e)
        {
            pictureBox1.Image = Pic;
            // Make a note that we "have the mouse".

            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)
        {
            Point px = p1;
            Point py = p2;

            // Convert the points to screen coordinates.
            p1 = PointToScreen(p1);
            p2 = 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.
            ControlPaint.DrawReversibleFrame(rc, Color.Black, FrameStyle.Dashed);

            rc.X = px.X;
            rc.Y = px.Y;

        }
        // Called when the left mouse button is released.
        public void MyMouseUp(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);
                Graphics graphics = pictureBox1.CreateGraphics();
                Pen pen = new Pen(Color.Gray, 2);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot;
                graphics.DrawRectangle(pen, rc);

            }
            // Set flags to know that there is no "previous" line to reverse.
            ptLast.X = -1;
            ptLast.Y = -1;
            ptOriginal.X = -1;
            ptOriginal.Y = -1;
        }
        // Called when the mouse is moved.
        public void MyMouseMove(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);
            }
        }

    }
}
like image 530
Umar Avatar asked Dec 28 '25 01:12

Umar


1 Answers

ControlPaint.DrawReversibleFrame uses screen co-ordinates to draw a rectangle on the screen (i.e. without respect to your application's windows) which is useful when acting upon drag mouse actions as the mouse may move outside of the application window. If you are using these very same co-ordinates raw to paint in your application, then they will be out as the co-ordinates on the control upon which you are painting are with respect to the control's origin (usually its top-left corner).

To use the screen co-ordinates, you first need to convert them into control co-ordinates using the PointToClient() or RectangleToClient() methods on the control upon which you are painting, e.g.

// panel`s OnPaint
Rectangle screenRectangle = ...
Rectangle clientRectangle = panel.RectangleToClient(screenRectangle);
graphics.DrawRectangle(Pens.Red, clientRectangle);
like image 56
Paul Ruane Avatar answered Dec 30 '25 15:12

Paul Ruane



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!