Рюхам MFC (и не только)
тебе точно не хватит ?
у меня еще один вопрос: создаю CBitmap функцией CreateBitmap. Там последний параметр - кусок в памяти, который по идее должен юзаться как то, что будет запихано в это CBitmap (как раз то, что мне нужно так по крайней мере в мсдн-е написано. Однако, когда дохожу до рисования, юзаю CBitmap::GetBitmap, однако в BITMAP-е параметр bmBits - нуль, как будто в мой битмап никто ниоткуда ничего не копировал .
void CDelmeDlg::OnGo
{
const int width = 256; // размеры картинки
const int height = 256;
char r[width][height]; // пусть картинка задана матрицами цветовых компонент
char g[width][height];// переделка для случая невыровненного массива BGRBGR... тривиальна
char b[width][height];
int x, y;
for(y=0; y < height; y++)
for(x=0; x < width; x++)
{
b[x][y] = y; // ну вот так извратно зададим нашу картинку
g[x][y] = x;
r[x][y] = y;
}
UINT scanline_bytes = (width * 3 + 3) / 4 * sizeof(DWORD); // это длина строки при DWORD alignment для 24 битов
UINT data_len = scanline_bytes * height;
char * data = (char*)::HeapAlloc(::GetProcessHeap 0, data_len); // выделяем буфер под выровненную картинку
ASSERT(data);
for(y=0; y < height; y++) // Заполняем буфер.
for(x=0; x < width; x++)
{
char* tmp = data + y * scanline_bytes + 3 * x ; // обеспечиваем выравнивание
*(tmp + 0) = b[x][y];
*(tmp + 1) = g[x][y];
*(tmp + 2) = r[x][y];
}
// к этому моменту у нас есть буфер с выровненными значениями RGB
// надо заполнить структуру с инфой о DIB'е
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
bmih.biXPelsPerMeter = 120;
bmih.biYPelsPerMeter = 120;
bmih.biWidth = 0;
bmih.biHeight = 0;
bmih.biWidth = width;
bmih.biHeight = height;
SIZE sz;
sz.cx = width, sz.cy = height;
CClientDC dc(this); // отрисовывать будем в клиентской области окна
// рисуем (поддерживается масштабирование, размеры на экране sz.cx и sz.cy)
::StretchDIBits(dc, 0, 0, sz.cx, sz.cy, 0, bmih.biHeight + 1, sz.cx,
-sz.cy, data, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, SRCCOPY);
ASSERT(::HeapFree(::GetProcessHeap 0, data; // вернули системе память
}
Если же неприменно хочется использовать CBitmap, который не Device Independent, а Device Dependent Bitmap, тогда так:
void CDelmeDlg::OnGo
{
const int width = 256;
const int height = 256;
char r[width][height];
char g[width][height];
char b[width][height];
int x, y;
for(y=0; y < height; y++)
for(x=0; x < width; x++)
{
b[x][y] = y;
g[x][y] = x;
r[x][y] = y;
}
UINT scanline_bytes = (width * 3 + 3) / 4 * sizeof(DWORD);
UINT data_len = scanline_bytes * height;
char * data = (char*)::HeapAlloc(::GetProcessHeap 0, data_len);
ASSERT(data);
for(y=0; y < height; y++)
for(x=0; x < width; x++)
{
char* tmp = data + y * scanline_bytes + 3 * x ;
*(tmp + 0) = b[x][y];
*(tmp + 1) = g[x][y];
*(tmp + 2) = r[x][y];
}
BITMAPINFOHEADER bmih;
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biPlanes = 1;
bmih.biBitCount = 24;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = 0;
bmih.biClrUsed = 0;
bmih.biClrImportant = 0;
bmih.biXPelsPerMeter = 120;
bmih.biYPelsPerMeter = 120;
bmih.biWidth = 0;
bmih.biHeight = 0;
bmih.biWidth = width;
bmih.biHeight = height;
SIZE sz;
sz.cx = width, sz.cy = height;
CClientDC dc(this);
// закомментим это и замутим с CBitmap
/*::StretchDIBits(dc, 0, 0, sz.cx, sz.cy, 0, bmih.biHeight + 1, sz.cx,
-sz.cy, data, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, SRCCOPY);*/
////////////////////////////////////////////////////////////////////////// <suxx>
CBitmap bmp;
CDC memDC;
bmp.CreateCompatibleBitmap(&dc, bmih.biWidth, bmih.biHeight); // создадим DDB совместимый с нашим конкретным device'ом
memDC.CreateCompatibleDC(&dc); // создадим совместимый контекст в памяти
::SetDIBits(dc, bmp, 0, bmih.biHeight, data, (LPBITMAPINFO)&bmih, DIB_RGB_COLORS); // пропишем нашу картинку в CBitmap
CBitmap* oldBmp = memDC.SelectObject(&bmp); // выберем наш DDB в контекст в памяти, указатель на старый DDB сохраним
dc.BitBlt(0, 0, bmih.biWidth, bmih.biHeight, &memDC, 0, 0, SRCCOPY); // отрисовка from in-memory to screen DC
memDC.SelectObject(oldBmp); // ящик водки и старый DDB обратно
//////////////////////////////////////////////////////////////////////////</suxx>
ASSERT(::HeapFree(::GetProcessHeap 0, data;
}
У меня вышеприведённый код делает то что надо. Успехов.
зайди сюда. Там товарищ вроде бы думает как ты и ему объясняют, что он таки не прав. Если коротко, то ты пытаешься с DDB обращаться, как с DIB.
"Там последний параметр - кусок в памяти, который по идее должен юзаться как то, что будет запихано в это CBitmap (как раз то, что мне нужно)". Если есть инет и желание, Оставить комментарий
okunek
Есть кусок памяти, в который запихана rgb картинка(3байта на пиксель). Как нужно создать CBitmap и как скопировать содержимое памяти в этот CBitmap? Только очень большая просьба, если можно, очень хотелось бы увидеть куски кода, а не названия отдельных функций, с помощью которых это делается. Буду очень благодарен.