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

解决GetPixel函数在Google Chrome中返回0无法正常工作的问题

解决GetPixel在Chrome窗口中返回0的问题

问题根源

Chrome默认启用硬件加速,窗口内容由GPU通过DirectComposition/DWM合成层渲染,而非传统GDI绘制方式。此时GetDC(window)获取的只是一个空的占位DC,无法读取到实际的像素数据,导致GetPixel始终返回0。

解决方案

临时测试方案:禁用Chrome硬件加速

  • 打开Chrome,访问chrome://settings/system
  • 关闭「使用硬件加速模式(如果可用)」选项
  • 重启Chrome后运行程序,GetPixel即可正常读取像素值

正式解决方案:用PrintWindow捕获窗口内容

PrintWindow可以绕过GDI限制,捕获硬件加速窗口的内容,步骤如下:

  1. 创建兼容DC和位图,匹配窗口客户区尺寸
  2. 调用PrintWindow将窗口内容绘制到位图
  3. 从位图中提取像素数据

修改后的完整代码:

#include <windows.h>
#include <iostream>
#include <tchar.h>

void handleGame(HWND& _window) {
    LPCWSTR windowClass = L"Chrome_WidgetWin_1";
    LPCWSTR windowName = L"Stack Overflow - Where Developers Learn, Share, & Build Careers - Google Chrome";
    _window = FindWindow(windowClass, windowName);
    while (_window == NULL) {
        std::cout << "failed" << std::endl;
        _window = FindWindow(windowClass, windowName);
        Sleep(1000);
    }
}

int main() {
    HWND window = NULL;
    while (true)
    {
        handleGame(window);
        
        if (GetAsyncKeyState(VK_NUMPAD1)) {
            RECT rect = {};
            GetClientRect(window, &rect);
            int width = rect.right - rect.left;
            int height = rect.bottom - rect.top;

            // 创建兼容DC和位图
            HDC hdcScreen = GetDC(NULL);
            HDC hdcMem = CreateCompatibleDC(hdcScreen);
            HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, width, height);
            HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);

            // 捕获窗口客户区内容
            PrintWindow(window, hdcMem, PW_CLIENTONLY);

            COLORREF characteristic_color = 5460819;
            bool found = false;
            POINT targetPos = {0,0};

            // 读取位图中的像素
            BITMAP bmp;
            GetObject(hBitmap, sizeof(BITMAP), &bmp);
            BITMAPINFOHEADER bi = {0};
            bi.biSize = sizeof(BITMAPINFOHEADER);
            bi.biWidth = bmp.bmWidth;
            bi.biHeight = -bmp.bmHeight; // 负号表示从上到下的像素顺序
            bi.biPlanes = 1;
            bi.biBitCount = 32;
            bi.biCompression = BI_RGB;

            DWORD* pixels = new DWORD[width * height];
            GetDIBits(hdcMem, hBitmap, 0, height, pixels, (BITMAPINFO*)&bi, DIB_RGB_COLORS);

            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    COLORREF color = pixels[y * width + x];
                    if (color == characteristic_color) {
                        std::cout << "FOUND!" << std::endl;
                        targetPos.x = x;
                        targetPos.y = y;
                        found = true;
                        goto cleanup; // 找到后直接跳转到资源释放
                    }
                }
            }

cleanup:
            // 释放资源
            delete[] pixels;
            SelectObject(hdcMem, hOldBitmap);
            DeleteObject(hBitmap);
            DeleteDC(hdcMem);
            ReleaseDC(NULL, hdcScreen);

            if (found) {
                // 转换客户区坐标为屏幕坐标
                ClientToScreen(window, &targetPos);
                SetCursorPos(targetPos.x, targetPos.y);
            } else {
                std::cout << "not found..!" << std::endl;
            }

            break;
        }
    }
    std::cout << "end" << std::endl;
    return 0;
}

代码关键点说明

  • PrintWindow(window, hdcMem, PW_CLIENTONLY):仅捕获窗口客户区内容,避免包含标题栏等非目标区域
  • GetDIBits:将位图数据读取到内存数组中,方便遍历像素
  • ClientToScreen:将客户区坐标转换为屏幕坐标,确保SetCursorPos定位正确
  • 所有GDI资源(DC、位图)使用后必须释放,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 08:35:33