To create and save a
Grayscale image, you can do something like that:
struct CUSTOM_BITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[256];
};
BOOL SaveGrayScale(const BYTE* image, int width, int height, LPCTSTR fileName)
{
int fullWidth = (width + 3) & 0xfffffffc;
BYTE* bytes = new BYTE[fullWidth * height];
for (int i = 0; i < height; i++)
CopyMemory(bytes + i * fullWidth, image + i * width, width);
BITMAPFILEHEADER header;
ZeroMemory(&header, sizeof(BITMAPFILEHEADER));
header.bfType = ((WORD) ('M' << 8) | 'B');
header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(CUSTOM_BITMAPINFO) + fullWidth * height;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(CUSTOM_BITMAPINFO);
CUSTOM_BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(CUSTOM_BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 8;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = 0;
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
for (int i = 0; i < 256; i++)
{
bitmapInfo.bmiColors[i].rgbRed = 0;
bitmapInfo.bmiColors[i].rgbGreen = 0;
bitmapInfo.bmiColors[i].rgbBlue = i;
bitmapInfo.bmiColors[i].rgbReserved = 0;
}
HANDLE hFile = CreateFile(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
delete [] bytes;
return FALSE;
}
DWORD writtenBytes = 0;
if ( !WriteFile(hFile, &header, sizeof(BITMAPFILEHEADER), &writtenBytes, NULL) || writtenBytes != sizeof(BITMAPFILEHEADER)
|| !WriteFile(hFile, &bitmapInfo, sizeof(CUSTOM_BITMAPINFO), &writtenBytes, NULL) || writtenBytes != sizeof(CUSTOM_BITMAPINFO)
|| !WriteFile(hFile, bytes, fullWidth * height, &writtenBytes, NULL) || writtenBytes != fullWidth * height)
{
delete [] bytes;
CloseHandle(hFile);
return FALSE;
}
CloseHandle(hFile);
return TRUE;
}
void Test()
{
int width = 199;
int height = 200;
BYTE* image = new BYTE[width * height];
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
image[y * width + x] = x;
SaveGrayScale(image, width, height, "c:\\test.bmp");
delete [] image;
}
To get the information from an existing bitmap:
CBitmap bitmap;
...
BITMAP bmp;
bitmap.GetBitmap(&bmp);
int width = bmp.bmWidth;
int height = bmp.bmHeight;
int fullWidth = (width + 3) & 0xfffffffc;
BYTE* bytes = (BYTE*)bmp.bmBits;
...