我正在尝试创建一个简单的屏幕共享程序,其中包含一个 C++ 服务器和一个 C# 客户端。我目前正在尝试通过发送从 BitBlt
获得的缓冲区并通过网络发送它来实现这一点。这一切似乎都很好,但是当我尝试在我的 C# 客户端中读取缓冲区时,图像看起来一团糟。一个例子:
我用来在 C++ 端获取缓冲区的代码(在某处找到这段代码):
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);
}
我用来在 C# 端显示图像的代码:
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;
}));
老实说,我不知道发生了什么。
编辑
一些附加信息:
屏幕宽度:1366(客户端和服务器)
屏幕高度:768(客户端和服务端也一样)
对于缓冲区大小,我只是简单地使用 width * height * 3,在本例中为 3147264
最佳答案
在您的 C++ 代码中,您有:bmi.biBitCount = 24;
但在 C# 中,您使用位图的默认像素格式。这是 PixelFormat32bppArgb
。这意味着它每个像素使用 32 位。如果你使用
Bitmap bitmap = new Bitmap(clientWidth, clientHeight, PixelFormat.Format24bppRgb);
这可能会解决问题。
关于c# - C++ 位图到 C# 位图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22796558/