0

I am trying to create a simple screenshare program, with a C++ server, and a C# client. I am currently trying to achieve this by sending the buffer you get from BitBlt, and sending that over the net. This all seems to go alright, but when I try to read the buffer in my C# client, the image looks messed up. An example: enter image description here

The code I'm using to get the buffer on the C++ end (Found this code somewhere):

void ScreenCap()
{
    HDC hdc = GetDC(NULL), hdcMem = CreateCompatibleDC (hdc);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdc, ScreenX, ScreenY);
    BITMAPINFOHEADER bmi = {0};
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;
    bmi.biWidth = ScreenX;
    bmi.biHeight = -ScreenY;
    bmi.biCompression = BI_RGB;
    SelectObject(hdcMem, hBitmap);
    BitBlt(hdcMem, 0, 0, ScreenX, ScreenY, hdc, 0, 0, SRCCOPY);
    int res = GetDIBits(hdc, hBitmap, 0, ScreenY, ScreenData, (BITMAPINFO*)&bmi, DIB_RGB_COLORS);
    DeleteObject(hBitmap);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdc);
}

Code I'm using to display the image on the C# end:

char[] buffer = packet.getData();
Bitmap bitmap = new Bitmap(clientWidth, clientHeight);
BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, clientWidth, clientHeight), ImageLockMode.ReadWrite, bitmap.PixelFormat);
Marshal.Copy(Helper.toByteArray(buffer), 0, bData.Scan0, buffer.Length);
bitmap.UnlockBits(bData);

pictureBox1.Invoke(new Action(() =>
{
    pictureBox1.Image = bitmap;
}));

I honestly have no idea whats going on.

EDIT

Some additional information:

Screen Width: 1366 (Both in client and the server)

Screen Height: 768 (Also both the same, in client and server)

For the buffer size, I am simply just using width * height * 3, in this case its 3147264

9
  • Looks like a pixel is being added to each line. Commented Apr 1, 2014 at 20:51
  • Out of the blue: You are reading your bitmap in C++ as 24 bit RGB but in C# you are using the default pixel format which is 32bpp. Could you post the values of buffer.Length, clientWidth and clientHeight? And also there might be some confusion: sizeof(char) in C++ is guaranteed to be 1, in .NEt its usually 2. Commented Apr 1, 2014 at 20:52
  • You can take screenshot from C# code. If that's an option, see this Commented Apr 1, 2014 at 20:53
  • Yes Muepe, give me one second. I'll add them to the question. EDIT Added them to the question Commented Apr 1, 2014 at 20:54
  • 1
    Try this once: Bitmap bitmap = new Bitmap(clientWidth, clientHeight, PixelFormat.Format24bppRgb); Commented Apr 1, 2014 at 21:04

1 Answer 1

2

In your C++-Code you have: bmi.biBitCount = 24; but in C# you use the default pixelformat for the bitmap. This is PixelFormat32bppArgb. That means that it uses 32 bits per pixel. If you use

Bitmap bitmap = new Bitmap(clientWidth, clientHeight, PixelFormat.Format24bppRgb);

This might fix the problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.