c++socketswinapigdibitblt

Image sent over TCP is flipped


I created an client which sends a screenshot over TCP to an server.The image is sent successfully. However at receival the image is upside down(I know this is set by the negative height in one of the structure's properties). I've searched over the internet on the means of doing it, but I couldn't find a proper way to achieve this.So if there's a better way of doing it , please do correct me.

This is how I send the screenshot (client) :

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
//.....

I am sure the message is being sent and received properly as I have implemented a protocol for separating the packets.This is not the problem .

This is the receiver (server) :

// 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);

The image is upside down .How can I fix it ?


Solution

  • Thanks to @Igor Tandetnik I solved this problem .This is the final code:

    On the client i send BITMAPINFO instead of BITMAPINFOHEADER:

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

    Server side(I used CreateDIBSection instead of 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);