我从内存中的位图想得到其中的buffer数据,而且是32位的rgba 格式的,用下边的函数:
内存中的位图得buffer的方法:其中的回调可以得到数据
void CPaintManagerUI::BitmapCreate(HWND hWnd,HDC dc)
{
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
// Retrieve the handle to a display device context for the client
hdcWindow = dc;
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if (!hdcMemDC)
{
MessageBox(hWnd, "CreateCompatibleDC has failed", "Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
RECT rcClient;
GetWindowRect(hWnd, &rcClient);
//This is the best stretch mode
SetStretchBltMode(hdcWindow, HALFTONE);
// Create a compatible bitmap from the Window DC
hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
if (!hbmScreen)
{
MessageBox(hWnd, "CreateCompatibleBitmap Failed", "Failed", MB_OK);
goto done;
}
// Select the compatible bitmap into the compatible memory DC.
SelectObject(hdcMemDC, hbmScreen);
// Bit block transfer into our compatible memory DC.
if (!BitBlt(hdcMemDC,
0, 0,
rcClient.right - rcClient.left, rcClient.bottom - rcClient.top,
hdcWindow,
0, 0,
SRCCOPY))
{
MessageBox(hWnd, "BitBlt has failed", "Failed", MB_OK);
goto done;
}
// Get the BITMAP from the HBITMAP
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that
// call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc
// have greater overhead than HeapAlloc.
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char *lpbitmap = (char *)GlobalLock(hDIB);
// Gets the "bits" from the bitmap and copies them into a buffer
// which is pointed to by lpbitmap.
GetDIBits(hdcWindow, hbmScreen, 0,
(UINT)bmpScreen.bmHeight,
lpbitmap,
(BITMAPINFO *)&bi, DIB_RGB_COLORS);
if (m_fun_ptr) {
m_fun_ptr(lpbitmap, bmpScreen.bmWidth, bmpScreen.bmHeight);
}
bmp_write((unsigned char*)lpbitmap, bmpScreen.bmWidth, bmpScreen.bmHeight,
"d:\\123.bmp");
/*
// A file is created, this is where we will save the screen capture.
HANDLE hFile = CreateFile("d:\\captureqwsx.bmp",
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
// Add the size of the headers to the size of the bitmap to get the total file size
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
//Offset to where the actual bitmap bits start.
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
//Size of the file
bmfHeader.bfSize = dwSizeofDIB;
//bfType must always be BM for Bitmaps
bmfHeader.bfType = 0x4D42; //BM
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
*/
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Close the handle for the file that was created
//CloseHandle(hFile);
//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(hWnd, hdcWindow);
}
图像和视频开发中,经常需要将过程中的裸数据存到本地来看一下数据是否正确。由于bmp文件不需要进行编码所以称为了debug中常用的一种测试格式。在这里,保存一个不使用非c自带外部库保存本地bmp文件的函数,以免日后重复造车。
[cpp] view plain copy
- //test function for save local bmp
- int bmp_write(unsigned char *image, int imageWidth, int imageHeight, char *filename)
- {
- unsigned char header[54] = {
- 0x42, 0x4d, 0, 0, 0, 0, 0, 0, 0, 0,
- 54, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 32, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0
- };
- long file_size = (long)imageWidth * (long)imageHeight * 4 + 54;
- header[2] = (unsigned char)(file_size &0x000000ff);
- header[3] = (file_size >> 8) & 0x000000ff;
- header[4] = (file_size >> 16) & 0x000000ff;
- header[5] = (file_size >> 24) & 0x000000ff;
- long width = imageWidth;
- header[18] = width & 0x000000ff;
- header[19] = (width >> 8) &0x000000ff;
- header[20] = (width >> 16) &0x000000ff;
- header[21] = (width >> 24) &0x000000ff;
- long height = imageHeight;
- header[22] = height &0x000000ff;
- header[23] = (height >> 8) &0x000000ff;
- header[24] = (height >> 16) &0x000000ff;
- header[25] = (height >> 24) &0x000000ff;
- char fname_bmp[128];
- sprintf(fname_bmp, "%s.bmp", filename);
- FILE *fp;
- if (!(fp = fopen(fname_bmp, "wb")))
- return -1;
- fwrite(header, sizeof(unsigned char), 54, fp);
- fwrite(image, sizeof(unsigned char), (size_t)(long)imageWidth * imageHeight * 4, fp);
- fclose(fp);
- return 0;
- }
使用的方法如下:
[cpp] view plain copy
- char pc[] = "/data/a.dat";
- bmp_write(raw_image, pic_width, pic_height);
第一,这个函数接受的裸数据为32位的rgba数据。
第二,只是做save用,所以有可能应该是bgra数据 。