Рисование на растровом изображении в градациях серого 8bpp (неуправляемый C ++) - PullRequest
0 голосов
/ 29 июня 2010

Я безуспешно пытался нарисовать растровое изображение в градациях серого 8 бит на пиксель. Вот некоторые из моих попыток. Может быть, кто-то может указать, что я делаю неправильно.

=============================================== ====

Попытка 1: создать, выбрать и нарисовать:

В конструкторе:

CBitmap bm;
bm.CreateBitmap (200, 200, 1, 8, NULL);

В OnDraw:

CDC *mdc=new CDC ();
HGDIOBJ tmp = mdc->SelectObject(bm);

Результат: tmp равен NULL, что указывает на ошибку.

=============================================== ====

Попытка 2: CreateDIBSection

В конструкторе:

HBITMAP hbm;
BITMAPINFOHEADER bih;
BITMAPINFO bi;
HANDLE hb;
CDC* myDc = new CDC ();
HDC hdc = myDc->GetSafeHdc ();
void* bits;
RGBQUAD rq [256];

 initBi ();
 hbm = CreateDIBSection (hdc, &bi, DIB_RGB_COLORS, &bits, NULL, 0);

...

void CEightBitDrawingView::initBi()
{
 bih.biSize = sizeof (BITMAPINFOHEADER);
 bih.biWidth = 200;
 bih.biHeight = -200;
 bih.biPlanes = 1;
 bih.biBitCount = 8;
 bih.biCompression = BI_RGB;
 bih.biSizeImage = 0;
 bih.biXPelsPerMeter = 14173;
 bih.biYPelsPerMeter = 14173;
 bih.biClrUsed = 0;
 bih.biClrImportant = 0;

 memset ((void *) rq, 0, 256 * sizeof (RGBQUAD));

 bi.bmiHeader = bih;
 bi.bmiColors = rq;
}

Результат: он даже не компилируется, потому что член BITMAPINFO bmiColors определен как: RGBQUAD bmiColors [1];

, поэтому не будет принимать более одного цвета RGB. На самом деле, ничего, что я назначаю этому участнику, компилируется! (Могут ли они сделать это еще сложнее!?)

Любые предложения будут оценены! Спасибо!

=============================================== ====

Ответы [ 4 ]

4 голосов
/ 29 июня 2010

Здесь. Код, который демонстрирует, как - в неуправляемом мире - выделить динамически изменяемую структуру в стеке, заполнить ее и передать в CreateDIBSection.

#include <malloc.h>

HBITMAP CreateGreyscaleBitmap(int cx, int cy)
{
  BITMAPINFO* pbmi = (BITMAPINFO*)alloca( sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);
  pbmi->bmiHeader.biSize = sizeof (pbmi->bmiHeader);
  pbmi->bmiHeader.biWidth = cx;
  pbmi->bmiHeader.biHeight = cy;
  pbmi->bmiHeader.biPlanes = 1;
  pbmi->bmiHeader.biBitCount = 8;
  pbmi->bmiHeader.biCompression = BI_RGB;
  pbmi->bmiHeader.biSizeImage = 0;
  pbmi->bmiHeader.biXPelsPerMeter = 14173;
  pbmi->bmiHeader.biYPelsPerMeter = 14173;
  pbmi->bmiHeader.biClrUsed = 0;
  pbmi->bmiHeader.biClrImportant = 0;

  for(int i=0; i<256; i++)
  {
    pbmi->bmiColors[i].rgbRed = i;
    pbmi->bmiColors[i].rgbGreen = i;
    pbmi->bmiColors[i].rgbBlue = i;
    pbmi->bmiColors[i].rgbReserved = 0;
  }

  PVOID pv;
  return CreateDIBSection(NULL,pbmi,DIB_RGB_COLORS,&pv,NULL,0);
}
2 голосов
/ 30 июня 2010

В обоих примерах вы создали новый CDC со следующей строкой:

CDC* pDC = new CDC();

Но чего-то не хватает: Это просто создаст новый объект CDC, но без прикрепленного действительного дескриптора HDCк этому.Сначала необходимо вызвать CDC :: CreateCompatibleDC, иначе попытка выделить какой-либо объект в этом DC не удастся.

Относительно bmiColors: этот элемент определен как массив 1 размера, потому что данные за ним зависят от глубины цветаи тип растрового изображения.Это задокументировано в MSDN.Например, если у вас было 8-битное растровое изображение 128x128 пикселей, вам нужно было бы выделить следующее количество mem:

128 * 128 * sizeof(WORD) + sizeof(BITMAPINFOHEADER)
0 голосов
/ 07 июля 2010

Я наконец прибег к использованию графического инструмента .NET (Aurigma) для создания растрового изображения 8bpp и передал его дескриптор неуправляемому C ++.

Затем в C ++:

HDC memDc = CreateCompatibleDC (NULL);      
HGDIOBJ Obmp  = ::SelectObject(memDc, varLayer);  // Handle to 8-bit bitmap.

Я смог выбрать растровое изображение в CDC и рисовать на нем.Не на 100% неуправляемый, но это позволило мне рисовать в неуправляемом коде, что дает приемлемую скорость.

0 голосов
/ 29 июня 2010

Ваше растровое изображение должно быть совместимым (с той же глубиной цвета), что и контекст отображения, на котором вы собираетесь его отображать. Кроме того, растровые изображения 8 бит / пиксель не обязательно оттенки серого - это функция используемой палитры.

...