能用但性能极差,仅适合偶尔取色;GetPixel跨进程调用开销大,60fps循环中会导致卡顿;推荐Graphics.CopyFromScreen截1×1像素再读取,或BitBlt内存缓冲用于高频场景;WPF应改用RenderTargetBitmap。
用
快速读取鼠标坐标颜色,但别在循环里狂调
直接结论:能用,但性能极差,只适合偶尔点一下查色。windows api 的
是最简单的方式,它接收屏幕坐标(x, y),返回一个
,转成
就行。
常见错误是把它塞进 60fps 的鼠标跟踪循环里——CPU 占用瞬间飙高,还卡顿。因为每次调用都要跨进程、走 GDI、做坐标转换,本质是“截图单像素”,不是内存读取。
必须先用
获取鼠标位置,再传给
读的是**屏幕坐标系**,不是窗体客户区坐标,别忘了用
转换(如果真要读自己窗口某点,那得另说)
返回的
是 BGR 格式(低字节是蓝),不是 RGB,
会自动处理,但手撕位运算时容易翻车
.NET 6+ 推荐用
截一小块再取色
比
稳得多,尤其要连续采样(比如做取色器吸管功能)。原理是先截 1×1 像素区域到
,再用
读——这回是托管内存操作,快一个数量级。
关键点在于“截哪”:必须把鼠标屏幕坐标转成目标设备上下文的逻辑坐标。如果只是看当前屏幕颜色,就以
创建全屏图面;如果限定在某个窗口内,得先
拿窗口边界,再做偏移计算。
截 1×1 比截大图快,但别截 0×0——会抛
记得
和
,不然内存泄漏比颜色还显眼
多显示器环境下,鼠标可能在非主屏,
默认只对主屏有效,需用
判断并调整源坐标
高频采样场景必须上
+ 内存缓冲
要做实时色值监控(比如录屏分析、辅助瞄准),
和小图截取都扛不住。真正靠谱的是用
把整屏或指定区域拷进内存
,之后所有像素访问都是纯内存操作。
C知道
CSDN推出的一款AI技术问答工具
下载
这不是加个引用就能跑的事:要手动创建兼容 DC、分配 DIB Section、管理位图句柄。.NET 没封装这个路径,得 P/Invoke
、
、
,最后
一次拷完。
缓冲区复用很关键——别每帧 new
,重用同一块内存
拷贝区域越小越好,比如只要鼠标周围 5×5,就只拷那么大,别全屏
注意 GDI 对象泄漏:每个
都得配对
,
返回的老位图也要
WPF 或 WinUI 项目?绕开 GDI,走
路线
如果你不在 WinForms 里硬刚 GDI,而是用 WPF,别碰
。WPF 渲染走 DirectX,GDI 读不到 WPF 窗口内容(会读到黑或旧画面)。正确姿势是用
把目标
(比如整个窗口或某个
)渲染成位图,再用
数组取色。
限制也很明显:它只能抓 WPF 自己画的东西,抓不到其他进程窗口、任务栏、桌面图标——这点和 GDI 方案完全不同。所以“取鼠标下任意屏幕色”这个需求,在 WPF 里天然不成立,得切回 Win32 API。
构造时分辨率参数必须和目标控件实际像素尺寸一致,否则缩放失真
读
数组前,确保已调用
并等待完成(它异步)
数组是 BGRA 格式、每像素 4 字节、从左到右从上到下排布,索引计算别错位
事情说清了就结束。最常被忽略的是多显示器 DPI 缩放——GetCursorPos 返回的是物理像素坐标,但 BitBlt 或 CopyFromScreen 在高 DPI 下可能按逻辑坐标算,不校正的话颜色会偏移一两个像素。
GetPixelgetpixelcolorrefcolorGetCursorPosGetPixelGetPixelScreenToClientCOLORREFColor.FromArgb(ref)Graphics.CopyFromScreenGetPixelBitmapGetPixel(0, 0)Graphics.FromHwnd(IntPtr.Zero)GetWindowRectArgumentExceptionDispose()GraphicsBitmapCopyFromScreenScreen.FromPointBitBltGetPixelBitBltBitmapCreateCompatibleDCCreateDIBSectionSelectObjectBitBltBitmapCreateCompatibleDCDeleteDCSelectObjectDeleteObjectRenderTargetBitmapGetPixelRenderTargetBitmapVisualCanvasPixelsRenderTargetBitmapPixelsRender