简体   繁体   中英

How can i replace the image in pictureBox1 with a crop image of a drawn on the pictureBox1 rectangle area?

First i'm drawing a rectangle on the pictureBox1 with the mouse

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        rect = new Rectangle(e.X, e.Y, 0, 0);
        painting = true;
    }
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        rect = new Rectangle(
            rect.Left, 
            rect.Top, 
            Math.Min(e.X - rect.Left, pictureBox1.ClientRectangle.Width - rect.Left), 
            Math.Min(e.Y - rect.Top, pictureBox1.ClientRectangle.Height - rect.Top));
    }
    this.pictureBox1.Invalidate();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    if (painting == true)
    {
        using (Pen pen = new Pen(Color.Red, 2))
        {
            e.Graphics.DrawRectangle(pen, rect);
        }
    }
}

The variable rect is global Rectangle and painting is global bool.

Then I did inside the pictureBox1 mouseup event

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    pictureBox1.Image = SaveRectanglePart(pictureBox1.Image, rect);
}

And the method SaveRectanglePart

Bitmap bmptoreturn;
public Bitmap SaveRectanglePart(Image image, RectangleF sourceRect)
{
    using (var bmp = new Bitmap((int)sourceRect.Width, (int)sourceRect.Height))
    {
        using (var graphics = Graphics.FromImage(bmp))
        {
            graphics.DrawImage(image, 0.0f, 0.0f, sourceRect, GraphicsUnit.Pixel);
        }
        bmptoreturn = bmp;
    }

    return bmptoreturn;
}

What i want to do is when i finish drawing the rectangle in the mouseup event to clear the pictureBox1 and replace the image in there with the rectangle image only.

But i'm getting exception parameter not valid in the mouseup event

pictureBox1.Image = SaveBitmapPart(pictureBox1.Image, rect);

And should i dispose somewhere the variable bmptoreturn ?

In the function SaveRectanglePart the variable bmp is Dispose of before the function returns as a result of the using statement. You need to remove the using statement and the code should work.

Bitmap bmptoreturn;
public Bitmap SaveRectanglePart(Image image, RectangleF sourceRect)
{
    var bmp = new Bitmap((int)sourceRect.Width, (int)sourceRect.Height)
    using (var graphics = Graphics.FromImage(bmp))
    {
        graphics.DrawImage(image, 0.0f, 0.0f, sourceRect, GraphicsUnit.Pixel);
    }
    bmptoreturn = bmp;

    return bmptoreturn;
}

But we have the issue of what bmptoreturn and pictureBox1.Image were referencing before they were set. The old Image / Bitmap the reference will be lost in memory until garbage collection comes along to free their memory. To be a good programmer we need to Dispose of these Image / Bitmap when we are done with them.

Image tmp = bmptoreturn;
bmptoreturn = bmp;
if(tmp != null)
    tmp.Dispose();
...
Image tmp = pictureBox1.Image;
pictureBox1.Image = SaveBitmapPart(pictureBox1.Image, rect);
if(tmp != null)
    tmp.Dispose();

Also, I am not sure why you are using bmptoreturn but it is not needed in the code from what I can tell. You can simply return bmp if bmptoreturn is not being used elsewhere.

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