Click here to Skip to main content
Click here to Skip to main content

Copying graphics with BitBlt (.NET Style)

By , 29 Dec 2003
 

Introduction

When the basic GDI+ functions just won't do, what you want is back to API school. BitBlt quite simply makes copies of portions of the screen. This is done by accessing the Windows hDC and other low level mind numbing things.

First we most Declare the functions that are in the GDI32.DLL file so we can use them in VB.NET.

Declare Auto Function BitBlt Lib "GDI32.DLL" ( _
     ByVal hdcDest As IntPtr, _
     ByVal nXDest As Integer, _
     ByVal nYDest As Integer, _
     ByVal nWidth As Integer, _
     ByVal nHeight As Integer, _
     ByVal hdcSrc As IntPtr, _
     ByVal nXSrc As Integer, _
     ByVal nYSrc As Integer, _
     ByVal dwRop As Int32) As Boolean

Then I have created a special function that will copy the area of the screen specified by rectangleF.

Private Function copyRect(ByVal src As PictureBox, _ 
       ByVal rect As RectangleF) As Bitmap
     'Get a Graphics Object from the form
     Dim srcPic As Graphics = src.CreateGraphics
     'Create a EMPTY bitmap from that graphics
     Dim srcBmp As New Bitmap(src.Width, src.Height, srcPic)
     'Create a Graphics object in memory from that bitmap
     Dim srcMem As Graphics = Graphics.FromImage(srcBmp)

     'get the IntPtr's of the graphics
     Dim HDC1 As IntPtr = srcPic.GetHdc
     'get the IntPtr's of the graphics
     Dim HDC2 As IntPtr = srcMem.GetHdc

     'get the picture 
     BitBlt(HDC2, 0, 0, rect.Width, _ 
       rect.Height, HDC1, rect.X, rect.Y, 13369376)

     'Clone the bitmap so we can dispose this one 
     copyRect = srcBmp.Clone()

     'Clean Up 
     srcPic.ReleaseHdc(HDC1)
     srcMem.ReleaseHdc(HDC2)
     srcPic.Dispose()
     srcMem.Dispose()
     srcMem.Dispose()
End Function

Then all we need to do is call the function to return the image you want:

Dim bmp = CType(copyRect(src, _ 
    New RectangleF(0, 0, 50, src.Height)), Bitmap)    
dest.Image = bmp.CloneShorthand:

-or-

dest.Image = CType(copyRect(src, _ 
   New RectangleF(0, 0, 50, src.Height)), Bitmap).Clone

Either statement will clone the src image at (0,0,50, src.height) and return a bitmap object. I have simply then taken the bitmap object and cloned it into a picturebox so you can see the results.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Matthew Hazlett
Web Developer
United States United States
Member
I started programming for fun when I was about 10 on an Franklin Ace 1000.
 
I still do it just for fun but it has gotten me a few jobs over the years. More then I can say for my Microsoft Certifications. Smile | :)
 
The way I learned was by example, now its time to give back to the next generation of coders.
 


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralClon BitBlt Vb to .Net (Sub BitBlt2)memberMember 366877515 Aug '08 - 14:12 
Contantes y Apis
-------------------
Public Const SRCCOPY As Integer = &HCC0020
Public Const SRCINVERT As Integer = &H660046
Public Const SRCAND As Integer = &H8800C6
...
 
Declare Auto Function BitBlt Lib "GDI32.DLL" ( _
ByVal hdcDest As IntPtr, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As IntPtr, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As Int32) As Boolean
 
Function
-------------------
Public Sub BitBlt2(ByRef Destino As PictureBox, ByVal dX As Integer, ByVal dY As Integer, ByVal dW As Integer, ByVal dH As Integer, ByVal Origen As PictureBox, ByVal sX As Integer, ByVal sY As Integer, ByVal Flag As Integer)
Dim srcPic As Graphics = Destino.CreateGraphics 'Get a Graphics Object from the form
Dim orgPic As Graphics = Origen.CreateGraphics 'Get a Graphics Object from the to
 
Dim srcBmp As New Bitmap(src.Width, src.Height, srcPic) 'Create a EMPTY bitmap from that graphics
Dim srcMem As Graphics = Graphics.FromImage(srcBmp) 'Create a Graphics object in memory from that bitmap
 
Dim HDC1 As IntPtr = orgPic.GetHdc 'get the IntPtr's of the graphics
Dim HDC2 As IntPtr = srcMem.GetHdc 'get the IntPtr's of the graphics
 
'Set the picture
BitBlt(HDC2, dX, dY, dW, dH, HDC1, sX, sY, Flag)
 
'Clone the bitmap so we can dispose this one
If Not Destino.Image Is Nothing Then Destino.Image.Dispose()
Destino.Image = srcBmp.Clone
 
'Clean Up
orgPic.ReleaseHdc(HDC1)
orgPic.Dispose()
srcPic.Dispose()
srcMem.ReleaseHdc(HDC2)
srcMem.Dispose()
srcBmp.Dispose()
End Sub
 

Codigo a insertar (From, Control, class..)
-----------------------------------------------
Dest = Picturebox a recibir el dibujo.
Src = Picturbox con imagen.
Mask 0 Picturebox con imagen.
 
BitBlt2(dest, 0, 0, 47, 47, Src, 0, 0, SRCAND)
BitBlt2(dest, 0, 0, 47, 47, Mask, 0, 0, SRCINVERT)
 
Gracias a Matthew Hazlett.
Big Grin | :-D
Questioncoloring images in picture boxmembersurgunsum13 Nov '07 - 0:16 
hello,
 

I have a image in picturebox, and the other image in the background of the picturebox.
 
the background image is the same image which is in picturebox1.image but it is coloured with block of dark colors for each parts.
 
now if i click on the picture box , i have given the code to retrive the color (ARGB) of background image where i clicked and then i have to colour the foreground image with the selected color from palette ,
but its coloring the background itself
...
i am using this code...
for coloring
 
Sleepy | :zzz:
 
Private Sub DoFill(ByVal sender As Object, ByVal ea As EventArgs)
 
' translate point to client co-ordinates
 
Dim pt As Point = m_pb.PointToClient(Control.MousePosition)
 

 
Dim x As Integer = pt.X
 
Dim y As Integer = pt.Y
 
Dim hDC1, hDC, hBrush As IntPtr
 
Dim g As Graphics = m_pb.CreateGraphics()
 

 
' get color of pixel clicked on
 
Dim clr As Color = CType(m_pb.BackgroundImage, Bitmap).GetPixel(x, y)
 
Dim cl As Color = CType(m_pb.Image, Bitmap).GetPixel(x, y)

Dim gdi_clr As Color = Color.FromArgb(0, clr.B, clr.G, clr.R)
Dim gdi_cl As Color = Color.FromArgb(0, cl.B, cl.G, cl.R)
Try
 

' get our device context
 

hDC = g.GetHdc()

 

 
' create a solid brush
 
' NOTE: When using GDI, pass "A,B,G,R" to Color.FromARGB()
 
hBrush = CreateSolidBrush(Color.FromArgb(0, 0, 0, 255).ToArgb())
 
' select into the DC
 

 

 
Dim last As IntPtr = SelectObject(hDC, hBrush)
 
' fill it
 
ExtFloodFill(hDC, x, y, gdi_clr.ToArgb(), FLOODFILLSURFACE)
 

 

' restore last object
 
SelectObject(hDC, last)
 
' delete the brush
 
DeleteObject(hBrush)
 
'Catch e As Exception
 
'Throw (e)
 
Finally
 

' release the DC and dispose of the object
 
g.ReleaseHdc(hDC)
 

 
g.Dispose()
 
End Try
 

 
End Sub
 
thanks a lot

GeneralPrint ScreenmemberAliBong20 Aug '06 - 0:06 
I have copied all code down in a project but these bits are not 'liked'! Wiggly lines!
Dim bmp = CType(copyRect(src, _ 
    New RectangleF(0, 0, 50, src.Height)), Bitmap)    
dest.Image = bmp.CloneShorthand:

-or-

dest.Image = CType(copyRect(src, _ 
   New RectangleF(0, 0, 50, src.Height)), Bitmap).Clone
 
It is in these bits of code where I, in my limited knowledge, get lost in not having come across those things before. I get 'scr' and 'dest' 'thrown out'. It may be a normal routine for those who have done it before so how do I get the image. I hope this hasn't sounded rude but I can't learn if I am not shown the way. Thank you. David.
GeneralConverting the Code Above for Layered Windows and Cmd Line Arguments [modified]memberMeskibob20 Jul '06 - 19:01 
I'm trying to create an exe to perform a screen capture for users with layered windows (this will be in a Yahoo! Widget that has screen capture functionality, with users that most-likely have Widgets on their desktop that they want captured.) I currently have a "working" C# executable, but it does a complete screen capture of the regularly layered windows, no Widgets. From my searching on the net, using BitBlt with the CaptureBlt constant included seems like the next avenue for experimentation, and this article seems to be the closest to what I need.
I'm now simply trying to convert the code above (as well as the code in the various source-code files) into a single .vb file (through notepad and the command prompt compiler) that can accept a filename/location as a command-line argument (once compiled obviously) to provide a location to save the image. However, I'm currently going nowhere fast and I am looking for some guidance (specifically towards what I should cut out since I don't need any forms or picture boxes, and then how to accept the command-line argument). Thank you.
-Meskibob
 
-- modified at 1:02 Friday 21st July, 2006
Generalcode doesn't work with my version of vb.netmemberserendipity 223 May '06 - 14:10 
Hi,
 
if I copy and paste the function
Function copyRect and build
 
it breaks at the line
BitBlt(HDC2, 0, 0, rect.Width, _
rect.Height, HDC1, rect.X, rect.Y, 13369376)
 
with the error message
Value of type 'System.IntPtr' cannot be converted to 'Integer'.
 
Is it because my vb.net version is 2002?
 
Anyone have any ways around it?
 

 

 
Bill
GeneralMore memory problems with this examplememberMike.Anderson20 Dec '05 - 7:47 
This example project is great if I want to copy images a small number of times. If it is used repeatedly though I start to have problems with lack of memory and my whole system slows. e.g. if the second button is amended to copy the image 1000 times. Windows task manager shows large amounts of memory used that isnt released until the form is closed and the gdi objects count goes up to 2000+. I'm using Win 2000.
 
Does anyone know the reason for this?
 
(note: fixing the typo identified earlier has no effect on this)
 

 
Mike
GeneralRe: More memory problems with this examplememberMatthew Hazlett20 Dec '05 - 8:53 
Read the fix for memory leak message.
 
Most likely It's just a matter of disposing the objects.

 
Matthew Hazlett

GeneralGood work, thanks!memberPinhead7512 May '05 - 20:59 
This code helped me a lot solving a problem, creating a graphic and storing it in a bitmap.
I originally come from VC6++ and are used with CDCs. This looks quite similar and helped me a lot! Smile | :)
Thanks
 

Pin
Generalcopy invisible imagesmemberthecopymaster29 Sep '04 - 4:20 
is there a way to copy an image even it is not visible? like if it is out of the screen area or another window is above it. in this case the function shown here would copy the topmost window.
GeneralRe: copy invisible imagesmemberbskirkman26 Jan '06 - 12:37 
Hi, Did u ever find out how to copy the invisible/hidden area of screen ot bitmap or so ?

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 30 Dec 2003
Article Copyright 2003 by Matthew Hazlett
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid