2017-04-03 43 views
-1

我希望將BITMAPINFOHEADER轉換爲字節數組以通過TCP套接字連接發送它。我可以捕獲桌面屏幕,圖像位於BITMAPINFOHEADER。下面是我曾嘗試代碼:如何將BITMAPINFOHEADER轉換爲使用C++的字節數組

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); 
} 
+0

我不明白你的問題。 'bi'是一個結構,所以'&bi'可以轉換爲'char *',並且你知道'bi'的大小。你還需要什麼? –

回答

0

你不需要轉換它。 send()套接字函數將指針指向任意的內存緩衝區,因此您可以發送BITMAPINFOHEADER和像素數據原樣。唯一需要注意的是send()需要一個char*指針,但你可以只使用一種類型的鑄爲,如:

send(theSocket, (char*)&bi, sizeof(bi), 0); 
send(theSocket, lpbitmap, dwBmpSize, 0); 
+0

它的工作,但我有另一個問題。在接收端,我有一個C#插座,它將顯示這個接收到的圖像。但在將其轉換爲圖像時,會出現「參數無效」的異常。那我該如何解決這個問題? –

+0

@JithinJose應該作爲一個新問題發佈。並確保顯示您正在使用的實際代碼。 –

相關問題