本文介绍了如何使用C ++将BITMAPINFOHEADER转换为Byte数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我希望将 BITMAPINFOHEADER
转换为字节数组,以通过TCP套接字连接发送它.我可以捕获桌面"屏幕,并且图像位于 BITMAPINFOHEADER
中.下面是我尝试过的代码:
I wish to convert a BITMAPINFOHEADER
into a byte array to send it over a TCP socket connection. I can capture the Desktop screen, and the image is in a BITMAPINFOHEADER
. Below is the code I have tried:
void CaptureAndSendScreen()
{
HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;
HWND hWnd = GetDesktopWindow();
// Retrieve the handle to a display device context for the client
// area of the window.
hdcScreen = GetDC(NULL);
hdcWindow = GetDC(hWnd);
// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow);
if(!hdcMemDC)
{
//MessageBox(hWnd, L"CreateCompatibleDC has failed",L"Failed", MB_OK);
goto done;
}
// Get the client area for size calculation
RECT rcClient;
GetClientRect(hWnd,&rcClient);
//This is the best stretch mode
SetStretchBltMode(hdcWindow,HALFTONE);
//The source DC is the entire screen and the destination DC is the current window (HWND)
if(!StretchBlt(hdcWindow,
0,0,
rcClient.right, rcClient.bottom,
hdcScreen,
0,0,
GetSystemMetrics (SM_CXSCREEN),
GetSystemMetrics (SM_CYSCREEN),
SRCCOPY))
{
MessageBox(hWnd, "StretchBlt has failed","Failed", MB_OK);
goto done;
}
// 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);
// **need to convert bi into Byte array and send through TCP socket**
//Unlock and Free the DIB from the heap
GlobalUnlock(hDIB);
GlobalFree(hDIB);
//Clean up
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL,hdcScreen);
ReleaseDC(hWnd,hdcWindow);
}
推荐答案
您无需转换. send()
套接字函数使用一个指向任意内存缓冲区的指针,因此您可以按原样发送 BITMAPINFOHEADER
和像素数据.唯一需要注意的是 send()
需要一个 char *
指针,但是您可以为此使用类型转换,例如:
You don't need to convert it. The send()
socket function takes a pointer to an arbitrary memory buffer, thus you can send the BITMAPINFOHEADER
and pixel data as-is. The only caveat is send()
expects a char*
pointer, but you can just use a type-cast for that, eg:
send(theSocket, (char*)&bi, sizeof(bi), 0);
send(theSocket, lpbitmap, dwBmpSize, 0);
这篇关于如何使用C ++将BITMAPINFOHEADER转换为Byte数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!