2017-02-18 58 views
0

我有一个32位整数(ARGB像素:uint32 *mypixels)和int widthint height阵列形式的位图图像。我需要将它们输出到打印机。如何绘制到设备上下文

我有打印机方面:HDC hdcPrinter;

当我了解,我需要先创建一个兼容方面:

HDC hdcMem = CreateCompatibleDC(hdcPrinter); 

然后我需要创建一个HBITMAP对象,选入兼容的情况下,并呈现:

HBITMAP hBitmap = ...? 
SelectObject(hdcMem, hBitmap); 
BitBlt(printerContext, 0, 0, width, height, hdcMem, 0, 0, SRCCOPY); 

最后清理:

DeleteObject(hBitmap); 
DeleteDC(hdcMem); 

我的问题是如何创建一个HBITMAP对象并将其放入mypixels

我发现了两个选项:

  1. HBITMAP hBitmap = CreateCompatibleBitmap(hdcPrinter, width, height);

    看起来不错,但你如何mypixels进入这个位图?

  2. HBITMAP hBitmap = CreateDIBSection(hdcPrinter /*or hdcMem?*/, ...);

    可以吗?它比选项1好吗?

+1

可以使用或[SetDIBits](https://msdn.microsoft.com/en-us/library/windows/desktop/dd162973(V = vs.85)的.aspx)之后[CreateCompatibleBitmap]( https://msdn.microsoft.com/en-us/library/windows/desktop/dd183488(v=vs.85).aspx) - 或者单独调用[CreateDIBitmap](https://msdn.microsoft .com/en-us/library/windows/desktop/dd183491(v = vs.85).aspx) - '从DIB创建兼容位图(DDB),并且可选地设置位图位' – RbMm

+0

很多方式,事情来自哪里。基本上来自文件,资源,内存位置。您必须关注位图的来源,代码片段会自动从任何基本的Google查询中弹出。注意代码中的错误,你永远不能忽略SelectObject()的返回值。设备上下文必须恢复,否则会导致内存泄漏。强烈建议使用库来做到这一点,也有助于避免使用谷歌搜索。 –

回答

0

该函数创建一个位图并将其设置为初始图像。 012rtIrt有点费劲地直接访问这些位,但它可以完成。

HBITMAP MakeBitmap(unsigned char *rgba, int width, int height, VOID **buff) 
{ 
    VOID *pvBits;   // pointer to DIB section 
    HBITMAP answer; 
    BITMAPINFO bmi; 
    HDC hdc; 
    int x, y; 
    int red, green, blue, alpha; 

    // setup bitmap info 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    bmi.bmiHeader.biWidth = width; 
    bmi.bmiHeader.biHeight = height; 
    bmi.bmiHeader.biPlanes = 1; 
    bmi.bmiHeader.biBitCount = 32;   // four 8-bit components 
    bmi.bmiHeader.biCompression = BI_RGB; 
    bmi.bmiHeader.biSizeImage = width * height * 4; 

    hdc = CreateCompatibleDC(GetDC(0)); 
    answer = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0x0); 
    for (y = 0; y < height; y++) 
    { 
     for (x = 0; x < width; x++) 
     { 
      red = rgba[(y*width + x) * 4]; 
      green = rgba[(y*width + x) * 4 + 1]; 
      blue = rgba[(y*width + x) * 4 + 2]; 
      alpha = rgba[(y*width + x) * 4 + 3]; 
      red = (red * alpha) >> 8; 
      green = (green * alpha) >> 8; 
      blue = (blue * alpha) >> 8; 
      ((UINT32 *)pvBits)[(height - y - 1) * width + x] = (alpha << 24) | (red << 16) | (green << 8) | blue; 
     } 
    } 
    DeleteDC(hdc); 

    *buff = pvBits; 

    return answer; 
} 
+0

谁负责清理'* buff'?需要哪个分配器来处理'* buff'?使用Get {R | G | B}值[color macros](https://msdn.microsoft.com/en-us/library/dd183456.aspx)以及[RGB宏](https://msdn.microsoft.com/en-us/library/dd162937.aspx)。评估alpha通道并设置它通常是没有必要的,因为GDI不支持alpha透明度。 – IInspectable

+0

@IInspectable - 'GDI不支持alpha透明度 - 是吗?奇怪为什么这为我工作。 – RbMm

+1

我相信* buff会在你调用hBitmap上的DeleteObject时死亡。你不应该试图释放它或者用你自己的分配器或者malloc()来分配它。 –