2017-08-09 110 views
1

我創建了一個客戶端,它通過TCP向服務器發送屏幕截圖。圖像發送成功。然而,在接收時,圖像是顛倒的(我知道這是由結構的一個屬性中的負高度設置的)。 我在互聯網上搜索的方式,但我找不到一個正確的方式來實現這一點。所以,如果有更好的方式做到這一點,請糾正我。通過TCP發送的圖像被翻轉

這是我送的截圖(客戶端):

HDC ScreenDC = GetDC(0); 
HDC hMemory = CreateCompatibleDC(ScreenDC); 
POINT ScreenSize = { GetDeviceCaps(ScreenDC, HORZRES),GetDeviceCaps(ScreenDC, VERTRES)}; 

// fill the hbitmap wtih the screenshot 
HBITMAP hBitmap = CreateCompatibleBitmap(ScreenDC, ScreenSize.x, ScreenSize.y); 
HGDIOBJ hOldBitmap = SelectObject(hMemory, hBitmap); 
BITMAPINFO bmpInfo = { 0 }; 

bmpInfo.bmiHeader.biSize = sizeof(bmpInfo.bmiHeader); 
GetDIBits(ScreenDC , hBitmap, 0, 0, NULL, &bmpInfo, DIB_RGB_COLORS); // fill bmpInfo with info about the hBitmap 
char * dataBuffer = new char[bmpInfo.bmiHeader.biSizeImage]; 

// adjust the header for our needs 
bmpInfo.bmiHeader.biBitCount = 32; 
bmpInfo.bmiHeader.biCompression = BI_RGB; // no compression -> easier to use 
bmpInfo.bmiHeader.biHeight = abs(bmpInfo.bmiHeader.biHeight); 
BitBlt(hMemory, 0, 0, ScreenSize.x, ScreenSize.y, ScreenDC, 0, 0, SRCCOPY); // take a screenshot 
GetDIBits(ScreenDC, hBitmap, 0, bmpInfo.bmiHeader.biHeight, dataBuffer, &bmpInfo, DIB_RGB_COLORS); // fill dataBuffer with raw image data 

// send first the bmpInfo.bmiHeader struct 
// send raw data : dataBuffer 
//..... 

我相信正在發送的消息,因爲我已經實現了一個協議,用於分離packets.This正確接收是沒有問題的。

這是接收器(服務器):

// data is the entire sent : structure + dataBuffer 

HDC hDc = GetDC(windowHwnd); 
HDC tCpyHdc = CreateCompatibleDC(hDc); 

BITMAPINFOHEADER bmpHeader = *(BITMAPINFOHEADER*)data; 
BITMAP bmp; 
bmp.bmType = 0; 
bmp.bmWidth = bmpHeader.biWidth; 
bmp.bmHeight = abs(bmpHeader.biHeight); 
bmp.bmPlanes = bmpHeader.biPlanes; 
bmp.bmWidthBytes = bmpHeader.biWidth * 4; 
bmp.bmBitsPixel = bmpHeader.biBitCount; 
bmp.bmBits = (char*)(data + sizeof(BITMAPINFOHEADER)); 

HBITMAP hB = CreateBitmapIndirect(&bmp); 

HBITMAP oldBmp = (HBITMAP)SelectObject(tCpyHdc, hB); 
StretchBlt(hDc, 0, 0, width - 20, height - 40, tCpyHdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); 

的圖像是上下顛倒我。如何解決這個問題?

+0

在發送端使用設備無關位圖(通過'GetDIBits'),但在接收端使用與設備相關的位圖(通過'CreateBi tmapIndirect')。我建議你也在接收端使用DIB,例如通過'CreateDIBSection' –

+0

我會測試它並回復它是否工作。謝謝 –

+0

你的意思是CreateDIBitmap也許?因爲我可以看到CreateDIBSection不會從數組中返回一個HBITMAP。我相信,基於HDC,它提供了一個陣列和一個HBITMAP。這不是我想要的服務器上。 –

回答

3

感謝@Igor Tandetnik我解決了這個問題。這是最後的代碼:

在客戶端我送BITMAPINFO而不是BITMAPINFOHEADER:

//... 
// send first the bmpInfo struct 
// send raw data : dataBuffer 
//..... 

服務器端(我用CreateDIBSection代替CreateBitmapIndirect的):

// data is the entire sent : structure + dataBuffer 

HDC hDc = GetDC(windowHwnd); 
HDC tCpyHdc = CreateCompatibleDC(hDc); 

BITMAPINFO bmpInfo = *(BITMAPINFO*)data; 
BITMAP bmp; 
bmp.bmType = 0; 
bmp.bmWidth = bmpInfo.bmiHeader.biWidth; 
bmp.bmHeight = -abs(bmpInfo.bmiHeader.biHeight); 
bmp.bmPlanes = bmpInfo.bmiHeader.biPlanes; 
bmp.bmWidthBytes = bmpInfo.bmiHeader.biWidth * 4; 
bmp.bmBitsPixel = bmpInfo.bmiHeader.biBitCount; 
bmp.bmBits = (char*)(data + sizeof(BITMAPINFO)); 

char* dibarr = NULL; 
HBITMAP hB = CreateDIBSection(windowData.tCpyHdc, &bmpInfo, DIB_RGB_COLORS, (void**)&dibarr, 0, 0); 
memcpy((void*)dibarr, (void*)bmp.bmBits, inf.packetsz - sizeof(BITMAPINFO)); 

HBITMAP oldBmp = (HBITMAP)SelectObject(tCpyHdc, hB); 
StretchBlt(hDc, 0, 0, width - 20, height - 40, tCpyHdc, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);