GDI+ Question - Copy drawn image

I've spent the last hour googling, searching this forum, and MSDN2 for what, I assumed, would be a simple process.  I have a picturebox that I've drawn in (via the Paint event).  I want to copy the information I've drawn on the picturebox (not the box's .Image property, which is nothing)  to the windows clipboard.

Short of resorting to the API and BitBlt how can I get what's drawn on the picturebox into the clipboard



Answer this question

GDI+ Question - Copy drawn image

  • imaginative_moin

    controls can utilize double buffering, so it must be turned off if manual caching took place.

  • EW16150

    you need to use the api there is an exampler on the vb-helper website


  • Merlinv

    Thanks for the suggestions, I appreciate it. I was hoping to avoid having to duplicate or isolate the drawing code in the paint event.
  • Sixto

    That is exactly what I was looking for Ken, thanks so much!

     

    - Edit:
        I came across that function when I was drilling through the picturebox methods and looked it up.  Here is the whole of the function description documentation from the MSDN library:

    Parameters

    bitmap

    The bitmap to be drawn to.

    targetBounds

    The bounds within which the control is rendered.

    Then there is a whole series of "Oh, don't use this for these things anyway..." things listed after that.   So perhaps a word to the documentation team for a code example or a "here's what you might use this for" description.

    http://msdn2.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap.aspx


  • jimc52

    I want to notice that Ken's sample will draw whole control, including any non-client area elements. It may be ok with picture box, but if you use other controls with borders or other non-client elements, then you should use ClientRectangle of that control.

  • Warren POiD

    I came up with that too, but I'm old and grouchy    I hate to have to modify code to accomodate lack of functionality, a simple BitMapObject = Image.FromhDC(Picturebox.hDC) would have made my day.

    Thanks again, both of you!


  • Brian Ekins

    You could also have a cached bitmap that holds the image you want to draw to the picture box - whatever code affects what is output on the picturebox should call a paint function that fills up the bitmap instead, and on the picture box's paint event you just use DrawImage to paint the bitmap on your picturebox. You could then just push the bitmap to the clipboard whenever requested. No duplication of code, and some perfomance benefits when compared to doing the paint actions twice. More memory consumption, though.



  • Cmore

    You can avoid this easily - Paint event handler can call helper method DoPaint(Graphics g) and same method can be called in Clipboard Copy handler.

     

    Also you can use InvokePaintBackground()/InvokePaint() methods in Control class. You can provide own Graphics to them and control will paint himself in your graphics (which can be from your bitmap).



  • esin gulten

    Hi!

    You can draw stuff in own bitmap and copy to clipboard this bitmap:

    Bitmap bitmap = new Bitmap(100, 200);

    using (Graphics g = Graphics.FromImage(bitmap))

    {

    // draw here

    }

    Clipboard.SetImage(bitmap);



  • Dale Levesque

    I understand it doesn't track it, but if I can accomplish what I want via GetWindowDC and BitBlt then surely the framework could have encapsulated that into an image, or bitmap, function.
  • CraigyBoop

    Unfortunately Image.FromHDC() idea won't work. GDI designed so it do not keep image once it was drawn, if image becomes invalid GDI will ask again to draw missing parts.

    But the method with InvokePaintBackground() and InvokePaint() must work and it's looks like what you ask.



  • rsm1235

    You could also use the new DrawToBitmap method added in vs 2005 to get the image

    Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint

    e.Graphics.Clear(Color.SkyBlue)

    e.Graphics.FillEllipse(Brushes.Green, 10, 10, 20, 20)

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    Dim bm As New Bitmap(PictureBox1.Width, PictureBox1.Height)

    PictureBox1.DrawToBitmap(bm, New Rectangle(0, 0, bm.Width, bm.Height))

    PictureBox2.Image = bm

    End Sub

    End Class



  • GDI+ Question - Copy drawn image