Using the BitBlt Function in GDI+

HTML clipboard

This article has been excerpted from book "Graphics Programming with GDI+".

One of the most frequently asked questions on discussion forums and newsgroups related to GDI in managed code has to do with the use of BitBlt. Is this because developers want to implement sprites and scrolling type actions in their applications? If you want to use the BitBlt function, you are probably aware of what it does. For the uninitiated, however, we should explain that this function performs a bit-block transfer of the color data corresponding to a rectangle of pixels from one device context to another. It is defined as follows:

bool BitBlt (
HDC hdcDest, //handle to destination device context
int nXdest, //x-coordinate of destination upper left corner
int nYdest, //y-coordinate of destination upper left corner
intnWidth, //width of destination rectangle
intnHeight, //height of destination rectangle
HDC hdcSrc, //hnadle to source device context
int nXSrc, //x-coordinated of source upper left corner
int nYSrc, //y-coordinated of source upper left corner
DWORD dwRop //raster operation code
);

More details of BitBlt are available in the GDI SDK documentation. Just type "BitBlt" in MSDN's index to find it.

First we need to import the BitBlt method and the Gdi32.dll library using the DllImportAttribute class.

[System.Runtime.InteropServices.DllImportAttribute ("Gdi32.dll"]
public static extern bool BitBlt (
intPtr hdcDest,
int nYdest,
int nWidth,
int nHeight,
IntPtr hdcSrc,
int nXsrc,
int nYSrc,
System.Int32 dwRop
);


Now we just call BitBlt. The code in Listing 14.2 uses the BitBlt function. As the function definition shows, we need source and destination device contexts. There is no concept of device context in managed code, but to maintain GDI interoperability, the Graphics class's GetHdc method is used to create a device context for a Graphics object (a surface). GetHdc returns an IntPtr object.

In Listing 14.2, first we create a Graphics object using CreateGraphics and we draw a few graphics items. From this Graphics object we create a Bitmap object and we create one more Graphics object as the destination surface by using the FromImage method of the Graphics object. Next we call BitBlt with destination and source device contexts as parameters. Finally, we make sure to call ReleaseHdc, which releases device context resources. The Save method saves a physical copy of the image. We also call the Dispose method of Graphics objects.

LISTING 14.2: Using the BitBlt function

private void Form1_Load (object sender, System.EventArgs e)
{
Graphics g1 = this.CreateGraphics();
Graphics g2 = null;
try
{
g1.SmoothingMode =
SmoothingMode.Antialias;
g1.DrawLine (new Pen (Color.Black, 2),
10, 10, 150, 10);
g1.DrawLine (new Pen (Color.Black, 2),
10, 10, 10, 150,);
g1.FillRectangle (Brushes.Blue, 30, 30, 70, 70);
g1.FillEllipse (new HatchBrush
(HatchStyle.DashedDownwardDiagonal, Color.Red, Color.Green),
110, 110, 100, 100);
Bitmap curBitmap = new Bitmap (
this.ClientRectangle.Width,
this.ClientRectangle.Height, g1);
g2 = Graphics.FromImage (curBitmap);
IntPtr hdc1 = g1.GetHdc();
IntPtr hdc2 = g1.GetHdc();
BitBlt (hdc2, 0, 0,
this.ClientRectangle.Width,
this.ClientRectangle.Height,
hdcl, 0, 0, 13369376);
g1.ReleaseHdc (hdc1);
g2.ReleaseHdc (hdc1);
curBitmap.Save ("f:\\BitBltImg.jpg",
ImageFormat.Jpeg);
}
catch (Exception exp)
{
MessageBox.Show (exp.Message.ToString());
}
finally
{
g2.Dispose();
g1.Dispose();
}
}

 

Book.jpg