1

I'm working with images like: https://i.stack.imgur.com/zmQr0.jpg

I've managed to find a vertical line between pages on scanned image. But sometimes there are some errors and I need to make an option for user to change this line position and angle. I think this would be nice within a PictureBox.

I need somehow to draw a line between two movable points on a picturebox with current image. When I move a point, position of line and it's angle have to be changed properly.

xZ6a33YaYEfmv
  • 1,816
  • 4
  • 24
  • 43

2 Answers2

2

Here is a sample code you can use for your need. It basically uses 4 events :
- Paint
- MouseDown
- MouseMove
- MouseUp

You can copy-paste this code to a form called Form1, with a picture box called pictureBox1

    int handleRadius = 3;
    int mPointMoveInProgress = 0;
    Point mPoint1, mPoint2;

    public Form1()
    {
        InitializeComponent();

        mPoint1 = new Point(50, 50); // Set correct default values
        mPoint1 = new Point(50, 300); // Set correct default values
    }

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        // Draw line
        e.Graphics.DrawLine(new Pen(Color.Black, 2), mPoint1, mPoint2);

        Rectangle rectangle;

        // Draw first handle
        rectangle = new Rectangle(mPoint1.X - handleRadius, mPoint1.Y - handleRadius, handleRadius * 2, handleRadius * 2);
        e.Graphics.FillRectangle(Brushes.White, rectangle);
        e.Graphics.DrawRectangle(Pens.Black, rectangle);

        // Draw second handle
        rectangle = new Rectangle(mPoint2.X - handleRadius, mPoint2.Y - handleRadius, handleRadius * 2, handleRadius * 2);
        e.Graphics.FillRectangle(Brushes.White, rectangle);
        e.Graphics.DrawRectangle(Pens.Black, rectangle);
    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        // Determine if a point is under the cursor. If so, declare that a move is in progress
        if (Math.Abs(e.X - mPoint1.X) < handleRadius && Math.Abs(e.Y - mPoint1.Y) < handleRadius) mPointMoveInProgress = 1;
        else if (Math.Abs(e.X - mPoint2.X) < handleRadius && Math.Abs(e.Y - mPoint2.Y) < handleRadius) mPointMoveInProgress = 2;
        else mPointMoveInProgress = 0;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (mPointMoveInProgress == 1) // If moving first point
        {
            mPoint1.X = e.X ;
            mPoint1.Y = e.Y ;
            Refresh();
        }
        else if (mPointMoveInProgress == 2) // If moving second point
        {
            mPoint2.X = e.X ;
            mPoint2.Y = e.Y ;
            Refresh();
        }
        else // If moving in the PictureBox: change cursor to hand if above a handle
        {
            if (Math.Abs(e.X - mPoint1.X) < handleRadius && Math.Abs(e.Y - mPoint1.Y) < handleRadius) Cursor.Current = Cursors.Hand;
            else if (Math.Abs(e.X - mPoint2.X) < handleRadius && Math.Abs(e.Y - mPoint2.Y) < handleRadius) Cursor.Current = Cursors.Hand;
            else Cursor.Current = Cursors.Default;
        }
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        // Declare that no move is in progress
        mPointMoveInProgress = 0;
    }

Damien
  • 106
  • 4
1

use Graphics class.

while there are new events about drawing (in mouse move handler or where it is needed):

// we don't need to change imageSource 
Image imgSourceCopy = imageSource.Clone as Image;

Graphics g = Graphics.FromImage(imgSourceCopy);

g.DrawLine(point1, point2);
pictureBox.Image = imgSourceCopy;

imgSourceCopy is used only for drawing line. p.s. hello from lviv :)

Sasha Reminnyi
  • 3,442
  • 2
  • 23
  • 27