• Welcome to Powerbasic Museum 2020-B.
 

GDI+: Locking Pixel Data for Writing from a User Input Buffer

Started by José Roca, June 22, 2008, 12:57:31 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
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 GdipBitmapLockBits function 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 GdipBitmapLockBits, 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 structure 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 structure with the attributes (width, height, format, and stride) of the pixel data buffer.

The code passes the address of the initialized BitmapData structure to the GdipBitmapLockBits function. The subsequent call to GdipBitmapUnlockBits copies the pixel data in the buffer to the Bitmap object.

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

C++


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);
}


PowerBASIC


SUB GDIP_LockBits3 (BYVAL hdc AS DWORD)

   LOCAL hStatus AS LONG
   LOCAL pGraphics AS DWORD
   LOCAL pBitmap AS DWORD
   LOCAL strFileName AS STRING
   LOCAL bmpData AS BITMAPDATA
   LOCAL rc AS RECT
   LOCAL row AS LONG
   LOCAL col AS LONG
   DIM   pxs(29, 49) AS DWORD

   hStatus = GdipCreateFromHDC(hdc, pGraphics)

   '  // Create a Bitmap object from a BMP file.
   strFileName = UCODE$("LockBitsTest3.bmp")
   hStatus = GdipCreateBitmapFromFile(STRPTR(strFileName), pBitmap)

   ' // Create and fill a pixel data buffer.
   FOR row = 0 TO 29
      FOR col = 0 TO 49
         pxs(row, col) = &HFF00FFFF  ' // aqua
      NEXT
   NEXT

   bmpData.Width = 50
   bmpData.Height = 30
   bmpData.Stride = 4 * bmpData.Width
   bmpData.PixelFormat = %PixelFormat32bppARGB
   bmpData.Scan0 = VARPTR(pxs(0))
   bmpData.Reserved = %NULL

   ' // Display the bitmap before locking and altering it
   hStatus = GdipDrawImageI(pGraphics, pBitmap, 10, 10)

   ' // Lock a 50x30 rectangular portion of the bitmap for writing
   SetRect rc, 20, 10, 50, 30
   hStatus = GdipBitmapLockBits(pBitmap, rc, %ImageLockModeWrite OR %ImageLockModeUserInputBuf, %PixelFormat32bppARGB, bmpData)

   ' // Commit the changes and unlock the 50x30 portion of the bitmap
   hStatus = GdipBitmapUnlockBits(pBitmap, bmpData)

   ' // Display the altered image
   hStatus = GdipDrawImageI(pGraphics, pBitmap, 150, 10)

   ' // Cleanup
   IF pBitmap THEN GdipDisposeImage(pBitmap)
   IF pGraphics THEN GdipDeleteGraphics(pGraphics)

END SUB