简体   繁体   中英

Drawing rectangle disappears after marking area to crop

Aim:

Draw a rectangle in red color and on release of left-mouse click. Keep the rectangle.

Code:

private void button1_Click(object sender, EventArgs e)
{
    if (Clipboard.ContainsImage())
    {
        pictureBox1.Image?.Dispose();
        pictureBox1.Image = Clipboard.GetImage();
    }
    else
    {
        MessageBox.Show("No Image detected in clipboard." + Environment.NewLine + "Have you print screened the label?", "Print Screen", MessageBoxButtons.OK, MessageBoxIcon.Warning);
    }
}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
        LocationXY = e.Location;
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        LocationX1Y1 = e.Location;
        pictureBox1.Invalidate();
    }
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        LocationX1Y1 = e.Location;

        pictureBox1.Invalidate();
        pictureBox2.Invalidate();
    }
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (MouseButtons == MouseButtons.Left)
    {
        e.Graphics.DrawRectangle(Pens.Red, GetRect());
    }
}

private void pictureBox2_Paint(object sender, PaintEventArgs e)
{
    var src = GetRect();

    if (src == Rectangle.Empty) return;

    var des = new Rectangle(0, 0, src.Width, src.Height);

    e.Graphics.DrawImage(pictureBox1.Image,
        des, src, GraphicsUnit.Pixel);
}


private Rectangle GetRect()
{
    return new Rectangle(
        Math.Min(LocationXY.X, LocationX1Y1.X),
        Math.Min(LocationXY.Y, LocationX1Y1.Y),
        Math.Abs(LocationXY.X - LocationX1Y1.X),
        Math.Abs(LocationXY.Y - LocationX1Y1.Y)
        );
}

private Bitmap GetCroppedImage()
{
    var des = GetRect();

    if (des == Rectangle.Empty) return null;

    var b = new Bitmap(des.Width, des.Height);

    using (var g = Graphics.FromImage(b))
    {
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.DrawImage(pictureBox1.Image, new Rectangle(0, 0, des.Width, des.Height), des, GraphicsUnit.Pixel);
    }
    return b;
}

Outcome:

On click of a button this print screened image shows up:

[![enter image description here][1]][1]

If I click and drag using left-mouse click, this red rectangle show up:

[![enter image description here][2]][2]

As soon as I release it:

[![enter image description here][1]][1]

Question:

How do I mark the area I'd like to crop and keep the red rectangle there? Without dissapearing

Because you are drawing the red rectangle only when the left mouse button is pressed,

it is not drawn by the consequent pictureBox1_Paint calls after the left mouse button is released.

With the following minor change, we can draw the red rectangle and make it persistent:

// Draw the red rectangle not only when
// the left mouse button is pressed
// but only when GetRect() is not empty
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    Rectangle currentSelection = GetRect();
    if (currentSelection != Rectangle.Empty)
    {
        e.Graphics.DrawRectangle(Pens.Red, currentSelection);
    }
}

Note: pictureBox2_Paint fails if pictureBox1.Image is null.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM