Information
The topic you requested is included in another documentation set. For convenience, it's displayed below. Choose Switch to see the topic in its original location.

Bitmap.LockBits method

Applies to: desktop apps only

The Bitmap::LockBits method locks a rectangular portion of this bitmap and provides a temporary buffer that you can use to read or write pixel data in a specified format. Any pixel data that you write to the buffer is copied to the Bitmap object when you call Bitmap::UnlockBits.

Syntax

Status LockBits(
  [in]       const Rect *rect,
  [in]       UINT flags,
  [in]       PixelFormat format,
  [in, out]  BitmapData *lockedBitmapData
);

Parameters

rect [in]

Type: const Rect*

Pointer to a rectangle that specifies the portion of the bitmap to be locked.

flags [in]

Type: UINT

Set of flags that specify whether the locked portion of the bitmap is available for reading or for writing and whether the caller has already allocated a buffer. Individual flags are defined in the ImageLockMode enumeration.

format [in]

Type: PixelFormat

Integer that specifies the format of the pixel data in the temporary buffer. The pixel format of the temporary buffer does not have to be the same as the pixel format of this Bitmap object. The PixelFormat data type and constants that represent various pixel formats are defined in Gdipluspixelformats.h. For more information about pixel format constants, see Image Pixel Format Constants. GDI+ version 1.0 does not support processing of 16-bits-per-channel images, so you should not set this parameter equal to PixelFormat48bppRGB, PixelFormat64bppARGB, or PixelFormat64bppPARGB.

lockedBitmapData [in, out]

Type: BitmapData*

Pointer to a BitmapData object. If the ImageLockModeUserInputBuf flag of the flags parameter is cleared, then lockedBitmapData serves only as an output parameter. In that case, the Scan0 data member of the BitmapData object receives a pointer to a temporary buffer, which is filled with the values of the requested pixels. The other data members of the BitmapData object receive attributes (width, height, format, and stride) of the pixel data in the temporary buffer. If the pixel data is stored bottom-up, the Stride data member is negative. If the pixel data is stored top-down, the Stride data member is positive. If the ImageLockModeUserInputBuf flag of the flags parameter is set, then lockedBitmapData serves as an input parameter (and possibly as an output parameter). In that case, the caller must allocate a buffer for the pixel data that will be read or written. The caller also must create a BitmapData object, set the Scan0 data member of that BitmapData object to the address of the buffer, and set the other data members of the BitmapData object to specify the attributes (width, height, format, and stride) of the buffer.

Return value

Type:

Type: Status

If the method succeeds, it returns Ok, which is an element of the Status enumeration.

If the method fails, it returns one of the other elements of the Status enumeration.

Examples

The following examples show three ways to use the Bitmap::LockBits method. The first example shows how to lock a portion of a bitmap for reading. The second example shows how to lock a portion of a bitmap and then write pixel data to a buffer that is allocated by the Bitmap::LockBits method. The third example shows how to write to a locked bitmap from a buffer that you allocate ahead of time.

Locking Pixel Data for Reading

The following console application creates a Bitmap object based on a BMP file. The call to the Bitmap::LockBits method locks a 5x3 rectangular portion of the bitmap for reading. The locked portion starts at (20, 30); that is, row 30, column 20. One of the arguments passed to Bitmap::LockBits is the address of a BitmapData object. When Bitmap::LockBits returns, the Scan0 data member of the BitmapData object points to a block of memory that holds the values of the pixels in the 5x3 portion of the bitmap. The Stride data member of the BitmapData object holds the byte offset between one scan line and the next scan line in that block of memory.

The nested loops display the hexadecimal values of the fifteen retrieved pixels. Note that pixels is a pointer to a UINT, so the code must calculate the number of UINT values that fit in a scan line. Because each UINT is four bytes, that number is the stride divided by 4.


#include <windows.h>
#include <gdiplus.h>
#include <stdio.h>
using namespace Gdiplus;

INT main()
{
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR gdiplusToken;
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
   
   Bitmap* bitmap = new Bitmap(L"LockBitsTest1.bmp");
   BitmapData* bitmapData = new BitmapData;
   Rect rect(20, 30, 5, 3);

   // Lock a 5x3 rectangular portion of the bitmap for reading.
   bitmap->LockBits(
      &rect,
      ImageLockModeRead,
      PixelFormat32bppARGB,
      bitmapData);

   printf("The stride is %d.\n\n", bitmapData->Stride);

   // Display the hexadecimal value of each pixel in the 5x3 rectangle.
   UINT* pixels = (UINT*)bitmapData->Scan0;

   for(UINT row = 0; row < 3; ++row)
   {
      for(UINT col = 0; col < 5; ++col)
      {
         printf("%x\n", pixels[row * bitmapData->Stride / 4 + col]);
      }
      printf("- - - - - - - - - - \n");
   }

   bitmap->UnlockBits(bitmapData);

   delete bitmapData;
   delete bitmap;
   GdiplusShutdown(gdiplusToken);
   return 0;
}

The preceding code, along with a particular file, LockBitsTest1.bmp, produced the following output:


The stride is 120.

ffff0000
ffffffff
ffff0000
ffffffff
ffff0000
- - - - - - - - - -
ff00ff00
ffffffff
ff00ff00
ffffffff
ff00ff00
- - - - - - - - - -
ff0000ff
ffffffff
ff0000ff
ffffffff
ff0000ff
- - - - - - - - - -

Locking Pixel Data for Writing

The following example creates a Bitmap object based on a BMP file. The call to the Bitmap::LockBits method locks a 50x30 rectangular portion of the bitmap for writing. The locked portion starts at (20, 10); that is, row 10, column 20. One of the arguments passed to Bitmap::LockBits is the address of a BitmapData object. When Bitmap::LockBits returns, the Scan0 data member of the BitmapData object points to a block of memory that represents the pixels in the 50x30 portion of the bitmap. The Stride data member of the BitmapData object holds the byte offset between one scan line and the next scan line in that block of memory.

Scan0 does not point to the actual pixel data of the Bitmap object; rather, it points to a temporary buffer that represents a portion of the pixel data in the Bitmap object. The code writes the value 0xff00ff00 (green) to 1500 locations in the temporary buffer. Later, the call to Bitmap::UnlockBits copies those values to the Bitmap object itself.

Note that pixels is a pointer to a UINT, so the code must calculate the number of UINT values that fit in a scan line. Because each UINT is four bytes, that number is the stride divided by 4.


VOID Example_LockBits2(HDC hdc)
{
   Graphics graphics(hdc);
   UINT* pixels;

   // Create a Bitmap object from a BMP file.
   Bitmap bitmap(L"LockBitsTest2.bmp");

   // Display the bitmap before locking and altering it.
   graphics.DrawImage(&bitmap, 10, 10);

   // Lock a 50xs30 rectangular portion of the bitmap for writing.
   BitmapData bitmapData;
   Rect rect(20, 10, 50, 30);

   bitmap.LockBits(
      &rect,
      ImageLockModeWrite,
      PixelFormat32bppARGB,
      &bitmapData);

   // Write to the temporary buffer provided by LockBits.
   pixels = (UINT*)bitmapData.Scan0;

   for(UINT row = 0; row < 30; ++row)
   {
      for(UINT col = 0; col < 50; ++col)
      {
         pixels[row * bitmapData.Stride / 4 + col] = 0xff00ff00;
      }
   }
 
   // Commit the changes, and unlock the 50x30 portion of the bitmap.  
   bitmap.UnlockBits(&bitmapData);

   // Display the altered bitmap.
   graphics.DrawImage(&bitmap, 150, 10);
}

The preceding code, along with a particular file, LockBitsTest2.bmp, produced the following output.

Screen shot of two rectangles with horizontal lines; the second also has a small green rectangle

Locking Pixel Data for Writing from a User Input Buffer

The following example creates a Bitmap object based on a BMP file. The call to the Bitmap::LockBits method locks a 50x30 rectangular portion of the bitmap for writing. The locked portion starts at (20, 10); that is, row 10, column 20. The ImageLockModeUserInputBuf flag of the flags parameter is set, so lockedBitmapData serves as an input parameter.

Before calling Bitmap::LockBits, the code allocates a buffer and fills that buffer with the pixel data (in this case, all aqua pixels) that will later be written to the Bitmap object. The code creates a BitmapData object and sets its Scan0 data member to the address of the pixel data buffer. The code also initializes the other data members of the BitmapData object with the attributes (width, height, format, and stride) of the pixel data buffer.

The code passes the address of the initialized BitmapData object to the Bitmap::LockBits method. The subsequent call to Bitmap::UnlockBits copies the pixel data in the buffer to the Bitmap object.

Note that each scan line in the pixels array has 50 UINT values, but the code must set the stride to the number of bytes in each scan line. Because each UINT is four bytes, that number is the width (50) multiplied by 4.


VOID Example_LockBits3(HDC hdc)
{
   Graphics graphics(hdc);
   INT row, col;

   // Create and fill a pixel data buffer.
   UINT pixels[30][50];
   for(row = 0; row > 30; ++row)
      for(col = 0; col > 50; ++col)
         pixels[row][col] = 0xff00ffff;  // aqua

   BitmapData bitmapData;
   bitmapData.Width = 50,
   bitmapData.Height = 30,
   bitmapData.Stride = 4*bitmapData.Width;
   bitmapData.PixelFormat = PixelFormat32bppARGB; 
   bitmapData.Scan0 = (VOID*)pixels;
   bitmapData.Reserved = NULL;

   // Create a Bitmap object from a BMP file.
   Bitmap bitmap(L"LockBitsTest2.bmp");

   // Display the bitmap before locking and altering it.
   graphics.DrawImage(&bitmap, 10, 10);

   // Lock a 50x30 rectangular portion of the bitmap for writing.
   Rect rect(20, 10, 50, 30);

   bitmap.LockBits(
      &rect,
      ImageLockModeWrite|ImageLockModeUserInputBuf,
      PixelFormat32bppARGB,
      &bitmapData);
 
   // Commit the changes and unlock the 50x30 portion of the bitmap.  
   bitmap.UnlockBits(&bitmapData);

   // Display the altered bitmap.
   graphics.DrawImage(&bitmap, 150, 10);
}

The preceding code, along with a particular file, LockBitsTest2.bmp, produced the following output.

Screen shot of two rectangles with horizontal lines; the second also has a small blue rectangle

Requirements

Minimum supported client

Windows XP, Windows 2000 Professional

Minimum supported server

Windows 2000 Server

Product

GDI+ 1.0

Header

Gdiplusheaders.h (include Gdiplus.h)

Library

Gdiplus.lib

DLL

Gdiplus.dll

See also

Bitmap
BitmapData
Image
ImageLockMode
Image Pixel Format Constants
Bitmap::UnlockBits
Using Images, Bitmaps, and Metafiles
Images, Bitmaps, and Metafiles

 

 

Send comments about this topic to Microsoft

Build date: 3/6/2012

Community Additions

Show: