Question

I am trying to convert hBitmap to array of bytes but I don't want to use TBitmap from unit Graphics. My input image is 128x64x32bit.

var TheBits: array of array of Cardinal;
begin   
  with info.bmiHeader do begin
    biWidth:=131;
    biHeight:=64;
    biSize:=SizeOf(TBITMAPINFOHEADER);
    biCompression:=BI_RGB;
    biBitCount:=32;
    biPlanes:=1;
    biSizeImage:=0;
  end; 

  DC := CreateCompatibleDC(0);    
  SetLength(TheBits, 128, 64);    
  GetDIBits(DC, BmpHandle, 0, 64,@TheBits[0][0],Info,DIB_RGB_COLORS);

This gives me a nice image (upside down, of course) but I had to put 131 into biWidth which doesn't really make sense to me. Why can't it be 128?

Was it helpful?

Solution

You were extremely lucky. Your array is actually 128 entirely separate arrays. When you set the dimensions, Delphi happened to allocate each array very close to the previous one, with 12 bytes separating them, accounting for the various bookkeeping data in each dynamic array. Lying by telling the API that your bitmap was 131 pixels wide made it skip those bytes when copying data for a narrower bitmap.

The API expects a single contiguous block of bytes, which is not what a multidimensional dynamic array is. A multidimensional dynamic array is really just seen ordinary dynamic array whose element type happens to be another dynamic array.

To fix your code, you need a single-dimension array; set its length to the product of the bitmap height and width.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top