0
votes

I have been working on creating a program similar to MS Paint. I have several of the features it has down but the one which is currently giving me trouble is the rectangular selection tool. My program currently draws everything on the panel and saves it all in an ArrayList so each shape can be redrawn in Paint().

Like MS paint I would like the user to be able to select a section of the drawing on the panel and either copy it, move it, re-size it, or even delete it. I was thinking about having the user draw a rectangle & saving the information for it. Then taking that information for the rectangle, passing them to create a new Bitmap. I would then paint a new rectangle in the background color to give the appearance that the selected area was "removed" when the selected portion is moved. It sounded okay until I realized that I couldn't use the Graphics.FromImage() on the PaintEventArgs variable passed to Paint() which made my idea useless. Not sure if that makes sense so my apologies if it's a confusing mess.

I've been searching the internet for some assistance and I haven't found much to help so either this is very easy to do, very difficult, or "rectangle selection tool" is not the proper term. Any help or pointers would be greatly appreciated!!! Thank you for your time! :)

1
It sounds like you have written a "draw" program, rather than a "paint" program. MS Paint does not remember each shape that's drawn, it just paints the shape onto the canvas, and remembers the canvas. That's why you can't move a rectangle after it's been finalized (you've clicked away). A rectangular selection tool would be a lot easier if you took the same approach. - Blorgbeard

1 Answers

1
votes

I understand that you actually have the Rectangle and now would like to copy an area from your painted Panel.

This is possible, assuming you have, as you should, placed all the painting in the Paint event of the Panel.

Then you can, use DrawToBitmap to ask the Panel to draw itself onto a new Bitmap; from there you can DrawImage the Rectangle onto your Panel.

Note: For this to integrate with your list of 'Paint-Actions' you will have to either now store that Bitmap or store the Rectangle and redo the whole operation.

using (Graphics G = panelCanvas.CreateGraphics() )
{
    Rectangle R0 = new Rectangle(22,22,55,55); // your Rectangle!
    using (Bitmap bmp = new 
           Bitmap(panelCanvas.ClientSize.Width, panelCanvas.ClientSize.Height))
    {    panelCanvas.DrawToBitmap(bmp, panelCanvas.ClientRectangle);
         G.DrawImage(bmp, 111f, 111f, R0, GraphicsUnit.Pixel);
    }
}

Aside: Please do replace the ArrayList, which is depracated by the new List<T>, e.g. a List<PaintAction> or whatever name your class has!

If you simply want to extract a rectanglular area from the Panel Control you can use thsi function:

public Bitmap getAreaFrom(Control ctl, Rectangle area)
{
    Bitmap bmp2 = new Bitmap(area.Width, area.Height);
    using (Graphics G = ctl.CreateGraphics())
    using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
    {
        ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
        using (Graphics G2 = Graphics.FromImage(bmp2))
            G2.DrawImage(bmp, 0f, 0f, area, GraphicsUnit.Pixel);
    }
    return bmp2;
}