无法将Bitmap绘制到窗口:远程截图传输程序故障排查求助
问题排查方案
画面持续缩小问题
- 检查服务端绘制逻辑:如果使用
BitBlt直接绘制,且窗口尺寸大于位图尺寸,或每次绘制错误将目标区域设为上一次的位图尺寸,会导致画面逐步缩小。应改用StretchBlt,以窗口客户区实际宽高作为目标参数,确保每次铺满窗口。 - 验证客户端截图尺寸:确认每次截图基于原始屏幕分辨率(通过
GetSystemMetrics(SM_CXSCREEN)/SM_CYSCREEN获取),而非复用旧位图尺寸,避免截图本身逐帧缩小。 - 检查
BITMAPINFOHEADER传输:服务端接收的biWidth和biHeight需与客户端发送的一致,若存在字节序错误、接收长度不足等解析问题,会导致位图尺寸被错误计算,进而绘制缩小。
内存占用激增问题
- 客户端资源泄漏:截图后未释放
HBITMAP、HDC等GDI对象,比如每次截图创建的hBitmap未调用DeleteObject销毁,会导致GDI资源和内存持续占用。 - 服务端内存泄漏:接收位图数据时动态分配的缓冲区(如
malloc分配的内存)未在绘制完成后释放,每帧传输都会新增内存占用,最终导致内存激增。 - 网络粘包处理:若未正确处理TCP粘包,可能导致服务端重复接收数据或内存堆积无效数据。需确保先完整接收
BITMAPINFOHEADER,再根据其中的尺寸计算缓冲区大小,精准接收位图数据。
代码检查要点
客户端
- 截图代码:确认每次获取的屏幕尺寸为原始分辨率,而非从旧位图中读取。
- 缓冲区计算:验证公式
DWORD bufferSize = ((bmi.biWidth * bmi.biBitCount + 31) / 32) * 4 * abs(bmi.biHeight);是否正确,避免缓冲区过小导致数据截断。 - 资源清理:截图完成后必须调用
DeleteObject(hBitmap)、ReleaseDC(NULL, hdcScreen)释放资源。
服务端
- 绘制代码:用
GetClientRect获取窗口客户区尺寸,调用StretchBlt(hdcDst, 0, 0, clientWidth, clientHeight, hdcSrc, 0, 0, bmi.biWidth, abs(bmi.biHeight), SRCCOPY);确保铺满窗口。 - 内存释放:接收位图数据的缓冲区,绘制完成后必须用
free或delete[]释放。 - GDI清理:创建的内存DC、位图对象,使用后需调用
DeleteDC、DeleteObject销毁。
内容的提问来源于stack exchange,提问作者AndroidAcolyteFX
相关产品推荐
相关产品推荐

