You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在屏幕显示像素向量?绘制截图顶部黑屏问题求助

问题原因与修复方案

你的代码存在三个核心问题,导致绘制时截图顶部出现黑屏:


1. 兼容位图创建时使用了错误的DC

setScreenSnippet中,CreateCompatibleBitmap(mem_dc, width, height)的mem_dc是刚创建的空兼容DC,默认关联单色位图,生成的位图无法存储32位RGB数据,导致部分区域显示黑色。

修复:改用屏幕DC创建兼容位图,确保格式与屏幕一致:

HBITMAP bitmap = CreateCompatibleBitmap(screen_dc, width, height);

2. DIB像素存储方向错误

当BITMAPINFO.bmiHeader.biHeight为正数时,DIB像素数据是从图像底部到顶部倒序存储的。你获取的像素顺序与绘制需求的顺序颠倒,导致图像错位,顶部出现黑屏。

修复:将biHeight设为负数,让DIB按从顶部到底部的顺序存储像素,与vector的线性存储一致:
在recvScreenSnippet和setScreenSnippet中,都修改:

bmi.bmiHeader.biHeight = -height;

3. DC资源清理逻辑错误

setScreenSnippet中没有保存SelectObject返回的旧位图句柄,无法正确恢复DC状态;且循环后的清理代码永远不会执行,存在资源泄漏。

修复:保存旧位图句柄,清理时恢复;调整循环逻辑(示例中添加了10秒后自动退出的条件)。


修改后的完整代码

截图生成函数

std::vector<RGBQUAD> recvScreenSnippet(int x, int y, int width, int height) {
    std::vector<RGBQUAD> v_screen_data(width*height);

    HDC screen_dc = GetDC(NULL);
    HDC mem_dc = CreateCompatibleDC(NULL);
    HBITMAP hBmp = CreateCompatibleBitmap(screen_dc, width, height);
    auto oldBmp = SelectObject(mem_dc, hBmp);

    // 32位 & 正序存储(biHeight为负)
    BITMAPINFO bmi{};
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biHeight = -height;  // 修改为负数
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biSize = sizeof(BITMAPINFO);

    BitBlt(mem_dc, 0, 0, width, height, screen_dc, x, y, SRCCOPY);
    GetDIBits(mem_dc, hBmp, 0, height, &v_screen_data[0], &bmi, DIB_RGB_COLORS);

    // 正确清理资源
    SelectObject(mem_dc, oldBmp);
    DeleteObject(hBmp);
    DeleteDC(mem_dc);
    ReleaseDC(0, screen_dc);

    return v_screen_data;
}

屏幕绘制函数

void setScreenSnippet(int x, int y, int width, int height, std::vector<RGBQUAD> &v_pixel_data) {
    HDC screen_dc = GetDC(0);
    HDC mem_dc = CreateCompatibleDC(0);

    // 32位 & 正序存储(biHeight为负)
    BITMAPINFO bmi{};
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biHeight = -height;  // 修改为负数
    bmi.bmiHeader.biWidth = width;
    bmi.bmiHeader.biSize = sizeof(BITMAPINFO);

    // 使用screen_dc创建兼容位图
    HBITMAP bitmap = CreateCompatibleBitmap(screen_dc, width, height);
    auto oldMemBmp = SelectObject(mem_dc, bitmap);  // 保存旧位图句柄

    SetDIBits(mem_dc, bitmap, 0, height, &v_pixel_data[0], &bmi, DIB_RGB_COLORS);

    // 示例:运行10秒后退出循环
    DWORD start_time = GetTickCount();
    while (GetTickCount() - start_time < 10000)
    {
        BitBlt(screen_dc, x, y, width, height, mem_dc, 0, 0, SRCCOPY);
        Sleep(1);
    }
    
    // 正确清理资源
    SelectObject(mem_dc, oldMemBmp);  // 恢复DC原来的位图
    DeleteObject(bitmap);
    DeleteDC(mem_dc);
    ReleaseDC(0, screen_dc);
}

调用代码

int main()
{   
    Sleep(5000);
    std::vector<RGBQUAD> v_pixel_data = recvScreenSnippet(600,600,400,400);
    setScreenSnippet(100, 600, 400, 400, v_pixel_data);

    system("pause");
    return 0;
}

内容的提问来源于stack exchange,提问作者Lenarolla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 02:32:42