CVB image to device independent (DIB) Bitmap idea

So, these are is just rough ideas to get from a CVB image to a DIB Bitmap or rather, a BITMAPINFO structure. The code and workflow has not been fully tested and surely could need improvement.

There are several ways that come to mind.

For instance one could copy the CVB image to the clipboard with AxCVImage.CopyImageToClipboard() and then do something like BITMAPINFO* bmp = (BITMAPINFO*)GetClipboardData(CF_DIB). As far as I’m aware, this has been worked in certain instances in the past.

Another approach that might work is to use the Device Context (DC) of Windows. First I’ve taken a function that creates a valid BITMAPINFO structure from DC.

PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp)
{
  BITMAP bmp;
  PBITMAPINFO pbmi;
  WORD    cClrBits;
  // Retrieve the bitmap color format, width, and height.
  if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))
  {
    //Do error handling here
  }
  // Convert the color format to a count of bits.
  cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);
  if (cClrBits == 1)
    cClrBits = 1;
  else if (cClrBits <= 4)
    cClrBits = 4;
  else if (cClrBits <= 8)
    cClrBits = 8;
  else if (cClrBits <= 16)
    cClrBits = 16;
  else if (cClrBits <= 24)
    cClrBits = 24;
  else cClrBits = 32;
  // Allocate memory for the BITMAPINFO structure. (This structure
  // contains a BITMAPINFOHEADER structure and an array of RGBQUAD
  // data structures.)
  if (cClrBits < 24)
    pbmi = (PBITMAPINFO)LocalAlloc(LPTR,
      sizeof(BITMAPINFOHEADER) +
      sizeof(RGBQUAD) * (1 << cClrBits));
  // There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel 
  else
    pbmi = (PBITMAPINFO)LocalAlloc(LPTR,
      sizeof(BITMAPINFOHEADER));
  // Initialize the fields in the BITMAPINFO structure.  
  pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  pbmi->bmiHeader.biWidth = bmp.bmWidth;
  pbmi->bmiHeader.biHeight = bmp.bmHeight;
  pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
  pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
  if (cClrBits < 24)
    pbmi->bmiHeader.biClrUsed = (1 << cClrBits);
  // If the bitmap is not compressed, set the BI_RGB flag.  
  pbmi->bmiHeader.biCompression = BI_RGB;
  // Compute the number of bytes in the array of color  
  // indices and store the result in biSizeImage.  
  // The width must be DWORD aligned unless the bitmap is RLE 
  // compressed. 
  pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) / 8
    * pbmi->bmiHeader.biHeight;
  // Set biClrImportant to 0, indicating that all of the  
  // device colors are important.  
  pbmi->bmiHeader.biClrImportant = 0;
  return pbmi;
}

Source: https://stackoverflow.com/questions/24720451/save-hbitmap-to-bmp-file-using-only-win32

Then you also need to get the CVB image to DC and use the function above.

void CVBImageToDC()
{
  // Image specs
  cvbdim_t width = ImageWidth((IMG)m_cvImg.GetImage());
  cvbdim_t height = ImageHeight((IMG)m_cvImg.GetImage());
  int dim = ImageDimension((IMG)m_cvImg.GetImage());
  int red = 0;
  int green = (dim >= 2) ? 1 : 0;
  int blue = (dim >= 3) ? 2 : 0;

// To DC
  HDC hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
  ImageToDC((IMG)m_cvImg.GetImage(), hDC,
            0, 0, 0, 0,
            width - 1, height - 1, width, height,
            red, green, blue,
            1.0, 0);

  // To DIB Bitmap
  HBITMAP hBitmap = CreateCompatibleBitmap(hDC, width, height);
  BITMAP bmpObject;
  GetObject(hBitmap, sizeof(BITMAP), &bmpObject);
  LONG size = bmpObject.bmWidthBytes * bmpObject.bmHeight;

  // Note: GetCurrentProcess() might be not reliable
  BITMAPINFO* bitmapinfo = CreateBitmapInfoStruct((HWND)GetCurrentProcess(), hBitmap);
}

And then you should have a working DIB Bitmap with bitmapinfo.

If someone has the capacities to thoroughly test this, feel free to do so and post your results or suggest alternative methods.