2017-02-18 57 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()來分配它。 –