Results 1 to 10 of 10

Thread: [RESOLVED] Get the image generated by Graphics into a bitmap

  1. #1

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Resolved [RESOLVED] Get the image generated by Graphics into a bitmap

    Inside PictureBox1_Paint I used PaintEventArgs parameter to draw some graphics and make transformations (rotation/scale).
    All changes are visible in the picturebox. Now I want to extract the image/bitmap updated, I mean, a bitmap with all that transformations I did, how to do it? The image in the picturebox is always Nothing.
    VB Code:
    1. Private Sub PictureBox1_Paint(ByVal sender As System.Object, _
    2.         ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint
    3.         e.Graphics.Clear(PictureBox1.BackColor)
    4.         RotateImage(e) 'Another sub
    5.         ZoomImage(e)   'Another sub
    6.         e.Graphics.DrawImage(MyBitmap, -PosX, -PosY) 'My bitmap drawn with transformation
    7.     End Sub
    There I send MyBitmap to be drawn by e.Graphics, but it's not 'transformed', it's just used to draw, How can I get the transfomed bitmap?
    Last edited by jcis; Mar 6th, 2006 at 08:20 PM.

  2. #2
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: From graphics created with PaintEventArgs to real image

    from the look of your code (without seeing the other routines source code)

    it looks like your modified image is in the MyBitmap variable when you are at this line of code, correct?
    VB Code:
    1. e.Graphics.DrawImage(MyBitmap, -PosX, -PosY) 'My bitmap drawn with transformation

    so you can just use that bitmap object. Unless I am missing something.

    Also, the reason the image in the picturebox is nothing, is because you are drawing the image directly to the DC of the picturebox, which is different than assigning an image property to it.

  3. #3

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: From graphics created with PaintEventArgs to real image

    Nope, the MyBitmap is never updated, e.Graphics has all the transformations, anything you send to it will be drawn using that transformations, a line, a rectanlge, or a bitmap, but the bitmap is never updated, it's never transformed, it's just used to draw, but the transformations are not reflected in the bitmap.
    Also, the reason the image in the picturebox is nothing, is because you are drawing the image directly to the DC of the picturebox, which is different than assigning an image property to it.
    Ok, then, is there any way to create a bitmap from that DC?
    Last edited by jcis; Mar 6th, 2006 at 04:12 PM.

  4. #4

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: From graphics created with PaintEventArgs to real image

    Bump.
    I just need to extract that transformed bitmap from there. The transformation is visible (rotation/scale), but I just can't find the way to extract that new image generated by System.Drawing.Graphics into a new bitmap.
    At least, anybody here knows how to get the DC of a picturebox?? This way, maybe I could use BitBlt or StrechBlt to get that image.

  5. #5
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Get the image generated by Graphics into a bitmap

    I think you can get the hdc like this
    VB Code:
    1. Dim hdc As IntPtr = e.Graphics.GetHdc()
    But there has to be a better way to do what you want to do...

  6. #6

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Get the image generated by Graphics into a bitmap

    Ok, then, that would be FromDc parameter for BitBlt, now I need DestDc, but VB.net Pictureboxes and bitmaps don't have hDC, like in VB6, at least i can't find it. Maybe I could use CreateCompatibleDC API but, I just can't believe that this stuff is not native in VB.net, weird.

  7. #7
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Get the image generated by Graphics into a bitmap

    OK, I think I figured it out.
    VB Code:
    1. Dim bm As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    2.         Dim g As Graphics = Graphics.FromImage(bm)
    3.         ' Draw your stuff here
    4.         RotateImage(g) 'Another sub
    5.         ZoomImage(g)   'Another sub
    6.         'now you have a bitmap you can use
    7.         PictureBox1.Image = bm
    8.         PictureBox2.Image = bm
    Last edited by moeur; Mar 7th, 2006 at 02:40 AM.

  8. #8

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Get the image generated by Graphics into a bitmap

    That should work, but for some reason, in this case, it doesn't.
    My project is attached.
    Attached Files Attached Files

  9. #9
    Old Member moeur's Avatar
    Join Date
    Nov 2004
    Location
    Wait'n for Free Stuff
    Posts
    2,712

    Re: Get the image generated by Graphics into a bitmap

    This exercise has forced me to learn a lot about the graphics object and graphics transformations.

    The way I handle this problem is to create a module-level graphics object which will handle all of our drawing. We can at any time access the contents of the grapics object through it's associated bitmap. We need two module-level bitmaps: one to hold the original picture which we will continually redraw to the graphics object; and the other to store the pixel data of the graphics object.

    At the Module level
    VB Code:
    1. [FONT=Courier New]    [COLOR=#0000FF]Private[/COLOR] OrigBitMap [COLOR=#0000FF]As[/COLOR] Bitmap
    2.     [COLOR=#0000FF]Private[/COLOR] bm [COLOR=#0000FF]As[/COLOR] Bitmap
    3.     [COLOR=#0000FF]Private[/COLOR] g [COLOR=#0000FF]As[/COLOR] Graphics[/FONT]
    In the form
    VB Code:
    1. [FONT=Courier New]        [COLOR=#007A00]'OrigBitMap will hold our original picture
    2. [/COLOR]        OrigBitMap = [COLOR=#0000FF]New[/COLOR] Bitmap(lAppPath & "[COLOR=#7A0000]\Tiger.bmp[/COLOR]")
    3.         PictureBox1.Width = CInt(OrigBitMap.Width * 2)
    4.         PictureBox1.Height = CInt(OrigBitMap.Height * 2)
    5.         PosX = CType((PictureBox1.ClientSize.Width - OrigBitMap.Width) / 2, [COLOR=#0000FF]Single[/COLOR])
    6.         PosY = CType((PictureBox1.ClientSize.Height - OrigBitMap.Height) / 2, [COLOR=#0000FF]Single[/COLOR])
    7.  
    8.         [COLOR=#007A00]'associate a bitmap (bm) with the drawing surface (g)
    9. [/COLOR]        [COLOR=#007A00]'make it the same size as our picturebox
    10. [/COLOR]        bm = [COLOR=#0000FF]New[/COLOR] Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    11.         g = Graphics.FromImage(bm)
    12.         [COLOR=#007A00]'our 1st transformation puts the image in the middle
    13. [/COLOR]        g.TranslateTransform(PosX, PosY, MatrixOrder.Append)
    14.         g.DrawImage(OrigBitMap, 0, 0)
    15.         [COLOR=#007A00]'show the image in the picturebox
    16. [/COLOR]        PictureBox1.Image = bm[/FONT]
    Note that all the transformations are cumulative. This means that if we want to rotate by a certain amount, we have to know how much we've rotated already. Same goes for scaling. Here are the new functions for rotation and scaling.
    VB Code:
    1. [FONT=Courier New]    [COLOR=#0000FF]Public[/COLOR] [COLOR=#0000FF]Sub[/COLOR] RotateImage([COLOR=#0000FF]ByVal[/COLOR] Gr [COLOR=#0000FF]As[/COLOR] Graphics, [COLOR=#0000FF]ByVal[/COLOR] mRotAngle [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR])
    2.         [COLOR=#0000FF]Static[/COLOR] OldAngle [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 0
    3.         [COLOR=#007A00]'move center of image to origin before rotating
    4. [/COLOR]        Gr.TranslateTransform(-CSng(PictureBox1.ClientSize.Width / 2), _
    5.         -CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append)
    6.         [COLOR=#007A00]'rotate image by the additional amount
    7. [/COLOR]        Gr.RotateTransform(mRotAngle - OldAngle, MatrixOrder.Append)
    8.         [COLOR=#007A00]'move image center back to picbox center
    9. [/COLOR]        Gr.TranslateTransform(CSng(PictureBox1.ClientSize.Width / 2), _
    10.         CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append)
    11.         [COLOR=#007A00]'clear old drawing
    12. [/COLOR]        Gr.Clear(PictureBox1.BackColor)
    13.         [COLOR=#007A00]'draw new image
    14. [/COLOR]        Gr.DrawImage(OrigBitMap, 0, 0)
    15.         [COLOR=#007A00]'save current rotation angle
    16. [/COLOR]        OldAngle = mRotAngle
    17.     [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub
    18. [/COLOR]
    19.     [COLOR=#0000FF]Public[/COLOR] [COLOR=#0000FF]Sub[/COLOR] ZoomImage([COLOR=#0000FF]ByVal[/COLOR] Gr [COLOR=#0000FF]As[/COLOR] Graphics, [COLOR=#0000FF]ByVal[/COLOR] scalex [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1, [COLOR=#0000FF]ByVal[/COLOR] scaley [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1)
    20.         [COLOR=#007A00]'move center of image to origin before scaling
    21. [/COLOR]        Gr.TranslateTransform(-CSng(PictureBox1.ClientSize.Width / 2), _
    22.         -CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append)
    23.         [COLOR=#007A00]'scale image by new factor
    24. [/COLOR]        Gr.ScaleTransform(scalex, scaley, MatrixOrder.Append)
    25.         [COLOR=#007A00]'move image center back to picbox center
    26. [/COLOR]        Gr.TranslateTransform(CSng(PictureBox1.ClientSize.Width / 2), _
    27.         CSng(PictureBox1.ClientSize.Height / 2), MatrixOrder.Append)
    28.         [COLOR=#007A00]'clear old drawing
    29. [/COLOR]        Gr.Clear(PictureBox1.BackColor)
    30.         [COLOR=#007A00]'draw new image
    31. [/COLOR]        Gr.DrawImage(OrigBitMap, 0, 0)
    32.     [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]
    And these are called from the trackbars like so
    VB Code:
    1. [FONT=Courier New]    [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] TrackRotation_Scroll([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, _
    2.     [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]Handles[/COLOR] TrackRotation.Scroll
    3.         [COLOR=#007A00]'perform a rotation transformation on the graphics object
    4. [/COLOR]        RotateImage(g, TrackRotation.Value)
    5.         [COLOR=#007A00]'show the results
    6. [/COLOR]        PictureBox1.Image = bm
    7.     [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub
    8. [/COLOR]
    9.     [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] TrackZoom_Scroll([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, _
    10.     [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]Handles[/COLOR] TrackZoom.Scroll
    11.         [COLOR=#0000FF]Static[/COLOR] oldScaleX [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1
    12.         [COLOR=#0000FF]Static[/COLOR] oldScaleY [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single[/COLOR] = 1
    13.         [COLOR=#0000FF]Dim[/COLOR] ScaleX [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single
    14. [/COLOR]        [COLOR=#0000FF]Dim[/COLOR] ScaleY [COLOR=#0000FF]As[/COLOR] [COLOR=#0000FF]Single
    15. [/COLOR]        [COLOR=#007A00]'Since all the transformations are cumulative,
    16. [/COLOR]        [COLOR=#007A00]'we have to keep track of the previous scaling factors
    17. [/COLOR]        [COLOR=#007A00]'differences in scaling are ratios
    18. [/COLOR]        [COLOR=#0000FF]If[/COLOR] ChkZoomX.Checked [COLOR=#0000FF]Then
    19. [/COLOR]            ScaleX = CType(TrackZoom.Value / 100 / oldScaleX, [COLOR=#0000FF]Single[/COLOR])
    20.             oldScaleX = CSng(TrackZoom.Value / 100)
    21.         [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]If
    22. [/COLOR]        [COLOR=#0000FF]If[/COLOR] ChkZoomY.Checked [COLOR=#0000FF]Then
    23. [/COLOR]            ScaleY = CType(TrackZoom.Value / 100 / oldScaleY, [COLOR=#0000FF]Single[/COLOR])
    24.             oldScaleY = CSng(TrackZoom.Value / 100)
    25.         [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]If
    26. [/COLOR]        [COLOR=#007A00]'scale the graphics object and display results
    27. [/COLOR]        ZoomImage(g, Scalex, Scaley)
    28.         PictureBox1.Image = bm
    29.     [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]
    Notice that in the TrackZoom Scroll we have to form the ratio of the previous zoom position to the new zoom position to get the new zoom factor. In the case rotation it is easier since rotation is additive.

    Finally, if you want to access the current image simply access the associated bitmap.
    VB Code:
    1. [FONT=Courier New]    [COLOR=#0000FF]Private[/COLOR] [COLOR=#0000FF]Sub[/COLOR] Button2_Click([COLOR=#0000FF]ByVal[/COLOR] sender [COLOR=#0000FF]As[/COLOR] System.Object, [COLOR=#0000FF]ByVal[/COLOR] e [COLOR=#0000FF]As[/COLOR] System.EventArgs) [COLOR=#0000FF]_
    2.        Handles[/COLOR] Button2.Click
    3.         [COLOR=#007A00]'How to save transformed image to file here?
    4. [/COLOR]        PictureBox2.Image = bm
    5.     [COLOR=#0000FF]End[/COLOR] [COLOR=#0000FF]Sub[/COLOR][/FONT]

  10. #10

    Thread Starter
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Get the image generated by Graphics into a bitmap

    Moeur, thank you from the heart man, that works perfectly
    As you said, transformations are cumulative that was not the case in my old code, I was using the Paint event of the picturebox sending always the original bitmap, it was transformed but temporary, and there was not way to save it. Now i see how transformations work. Thank you again!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width