c++ - 有没有办法在不复制所有像素的情况下将现有的像素数组转换为 BITMAP?

标签 c++ winapi mfc bitmap vtk

我需要将 vtkImageData 打印到打印机 CDC。 在查看 this 之后,我想到了这样做和 this . 一种是使用vtk接口(interface),设置一个CImage的像素,然后将CImage绘制到CDC:

CImage c_image;
c_image.Create(dims[0], dims[1], 24);
for (int y=0; y<dims[1]; y++)
{
  for (int x=0; x<dims[0]; x++)
  {
    float r = i_image->GetScalarComponentAsFloat(extent[0] + x, extent[2] + dims[1] - y - 1, 0, 0);
    float g = i_image->GetScalarComponentAsFloat(extent[0] + x, extent[2] + dims[1] - y - 1, 0, 1);
    float b = i_image->GetScalarComponentAsFloat(extent[0] + x, extent[2] + dims[1] - y - 1, 0, 2);
    c_image.SetPixelRGB(x, y, r, g, b);
  }
}

另一种方法是使用 CreateDIBSection() 然后将位图附加到 CImage 并将 CImage 绘制到 CDC:

HBITMAP hBitmap = nullptr;
  BITMAPINFOHEADER bmih;
  bmih.biSize     = sizeof(BITMAPINFOHEADER);
  bmih.biWidth    = dims[0];
  bmih.biHeight   = dims[1];
  bmih.biPlanes   = 1;
  bmih.biBitCount = i_image->GetNumberOfScalarComponents() * 8;
  bmih.biCompression  = BI_RGB ;
  bmih.biSizeImage    = 0;
  bmih.biXPelsPerMeter    =   10;
  bmih.biYPelsPerMeter    =   10;
  bmih.biClrUsed  =0;
  bmih.biClrImportant =0;

  BITMAPINFO dbmi;
  ZeroMemory(&dbmi, sizeof(dbmi));  
  dbmi.bmiHeader = bmih;
  dbmi.bmiColors->rgbBlue = 0;
  dbmi.bmiColors->rgbGreen = 0;
  dbmi.bmiColors->rgbRed = 0;
  dbmi.bmiColors->rgbReserved = 0;
  void* bits = nullptr;

  // Create DIB
  hBitmap = CreateDIBSection(i_printer_dc_ptr->GetSafeHdc(), &dbmi, DIB_RGB_COLORS, &bits, NULL, 0);
  if (hBitmap == nullptr) {
      ::MessageBox(NULL, __T("Could not load the desired image image"), __T("Error"), MB_OK);
      return;
  }
  ::memcpy(bits, i_image->GetScalarPointer(), i_image->GetNumberOfScalarComponents() * dims[0] * dims[1]);
  c_image.Attach(hBitmap);

两者都需要复制所有字节一次,然后打印到 CDC。有没有办法避免这种中间复制,直接将字节打印到 CDC?或者只是创建一个指向现有字节而不复制它们的 HBITMAP

最佳答案

是的,您可以使用 SetDIBitsToDevice()将位直接复制到 DC 的函数。

注意关于对齐的限制:

The scan lines must be aligned on a DWORD except for RLE-compressed bitmaps.

一个常见的问题是生成的位图最终颠倒(因为位图在 Windows 中是自下而上的)。如果发生这种情况,请在 BITMAPINFO 结构中取反高度。

关于c++ - 有没有办法在不复制所有像素的情况下将现有的像素数组转换为 BITMAP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19302807/

相关文章:

c++ - 为什么必须在哪里放置 “template”和 “typename”关键字?

c++ - 将成员函数指针传递到模板中

windows - 通过 WinAPI 和 Delphi 在 Skype 客户端中查找和使用当前事件的聊天框?

windows - 关于 Win32 ##Event## 同步对象的问题

javascript - 用于 MFC 应用程序的 Cef

c++ - 如何使用 MFC 创建 VST 插件?

c++ - [MFC]如何禁用combobox中的一个Item?

c++ - 旋转功能奇怪的行为

c++ - 左值到右值隐式转换

c++ - 获取打印页数