2017-02-18 3 views
0

У меня есть растровое изображение в виде массива из 32-битных целых чисел (ARGB-пиксели: uint32 *mypixels) и int width и int 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) - 'создает совместимое растровое изображение (DDB) из DIB и, опционально, устанавливает битовые биты' – RbMm

+0

Множество способов, где он исходит. В основном из файла, ресурса, ячейки памяти. Вам нужно будет сосредоточиться на источнике растрового изображения, фрагмент кода автоматически выплывает из любого основного запроса Google. Обратите внимание на ошибку в коде, вы никогда не сможете игнорировать возвращаемое значение SelectObject(). Контекст устройства должен быть восстановлен, неспособность сделать это вызывает утечку памяти. Рекомендуется использовать библиотеку для этого, также помогает избежать поиска в Интернете. –

ответ

0

Эта функция создает растровое изображение и устанавливает его на исходное изображение. Irt немного затруднительно получить доступ к битам напрямую, но это можно сделать.

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] Value' [цветные макросы] (https://msdn.microsoft.com/en-us/library/dd183456.aspx), а также [Макрос RGB] (https://msdn.microsoft.com/en-us/library/dd162937.aspx). Оценка альфа-канала и его настройка обычно не нужны, поскольку GDI не поддерживает альфа-прозрачность. – IInspectable

+0

@IInspectable - 'GDI не поддерживает альфа-прозрачность' - да? странно, почему эта работа для меня. – RbMm

+1

Я считаю, что * buff умирает, когда вы вызываете DeleteObject на hBitmap. Вы не должны пытаться освободить его или выделить его с помощью собственных распределителей или malloc(). –

Смежные вопросы