首页 > 解决方案 > 如何获取鼠标在桌面上的像素的 RGB 值?(GetPixel 不符合这一点......)

问题描述

我正在尝试制作一个 C++ 代码来打印鼠标光标每秒的像素的 rgb 值。我使用 GetDC(NULL) 用于桌面的 HDC,GetCursorPos(&pos) 用于鼠标光标的位置,getPixel(hDC, pos.x, pos.y) 用于鼠标光标指向的像素的 RGB 值。

这是我的完整 C++ 代码。

#include <iostream>
#include <Windows.h>

using namespace std;

int main(){

    POINT pos;
    int R;
    int G;
    int B;
    while (1) {
        GetCursorPos(&pos);
        HDC hDC = GetDC(NULL);
        COLORREF color=GetPixel(hDC, pos.x, pos.y);
        R = GetRValue(color);
        G = GetGValue(color);
        B = GetBValue(color);
        std::cout <<"x : "<<pos.x<<", y : "<<pos.y<<", R : "<< R <<", G : " <<G << ", B : "<<B << endl;
        ReleaseDC(NULL, hDC);
        Sleep(1000);
    }

    return 0;
}

当我编译这个时,它每秒打印一些像素的 rgb 值,但是,该像素与鼠标所在的像素不匹配。一开始我只是觉得可能是某个窗口的客户端有不同的点,或者我的笔记本总像素数小于1920x1080(实际上是1536x864),所以可能有bug,可以解决翻译要点。

但是,尽管在某些方面,它确实有效,但在大多数方面,它并没有奏效。

我尝试了一些测试。(代码使用 Visual Studio 2017 编译。)

在代码运行时,我用鼠标拖动控制台窗口。(注意控制台窗口的Non-client 窗口几乎是白色的,即RGB 值为(255, 255, 255)。) 所以,鼠标光标在控制台窗口上的相对位置不会改变。但是,打印的 rgb 值发生了变化!

我建议它可能与ppi有关,但我不知道为什么。

我应该怎么做和知道要获得鼠标光标指向的像素的 rgb 值?

标签: c++winapirgbpixel

解决方案


更新的答案:该解决方案似乎与@정재우 和 @Remy Lebeau 在评论中报告的系统的 DPI 设置和应用程序的 DPI 感知级别有关。在 Windows 10 中,相关设置可以在以下位置找到:

Settings -> Display -> Scale and Layout

如果此设置为 100%,则 OP 的代码可以正常工作。否则 GetCursorPos() 返回的坐标将被缩放。更多信息可以在以下文章中找到:

高 DPI 设备的 Windows 缩放问题

Windows 上的高 DPI 桌面应用程序开发

为进程设置默认 DPI 感知

原始答案(带有推测):您的代码似乎在我的机器上显示了正确的像素值,但是您可能会从不同的屏幕配置中得到不同的结果,例如当使用多个显示器时,主显示器左侧的坐标可以以负值给出。然而,在我使用多台显示器的 Windows 7 机器上,负鼠标坐标仍然可以正确转换。

此外,屏幕的“客户端”区域不包括任务栏等区域,至少我记得旧版本的 Windows 是这样工作的。要解决这种可能性,请尝试用 GetWindowDC() 或 GetDCEx(NULL,NULL,DCX_WINDOW) 替换您的 GetDC() 调用,看看您是否得到不同的结果。

为了帮助调试,请在 GetPixel() 调用之后直接添加以下调用以创建细微的红色像素伪影:

SetPixel(hdc,pos.x,pos.y,RGB(255,0,0));

这会在您刚刚读取像素值的同一位置在屏幕上放置一个红色像素。当您四处移动鼠标时,观察红色像素与实际鼠标光标的距离。


推荐阅读