c# - 如何读取屏幕像素的颜色

标签 c# winforms gdi+ pixel

好的,我正在寻找一个函数或其他东西来读取我显示器上某个像素的颜色,当检测到该颜色时,将启用另一个函数。我想使用 RGB。所有帮助表示赞赏。谢谢。

最佳答案

这是最有效的:它在光标位置抓取一个像素,而不依赖于只有一台显示器。

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;

namespace FormTest
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern bool GetCursorPos(ref Point lpPoint);

        [DllImport("gdi32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
        public static extern int BitBlt(IntPtr hDC, int x, int y, int nWidth, int nHeight, IntPtr hSrcDC, int xSrc, int ySrc, int dwRop);

        public Form1()
        {
            InitializeComponent();
        }

        private void MouseMoveTimer_Tick(object sender, EventArgs e)
        {
            Point cursor = new Point();
            GetCursorPos(ref cursor);

            var c = GetColorAt(cursor);
            this.BackColor = c;

            if (c.R == c.G && c.G < 64 && c.B > 128)
            {
                MessageBox.Show("Blue");
            }
        }

        Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb);
        public Color GetColorAt(Point location)
        {
            using (Graphics gdest = Graphics.FromImage(screenPixel))
            {
                using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
                {
                    IntPtr hSrcDC = gsrc.GetHdc();
                    IntPtr hDC = gdest.GetHdc();
                    int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, location.X, location.Y, (int)CopyPixelOperation.SourceCopy);
                    gdest.ReleaseHdc();
                    gsrc.ReleaseHdc();
                }
            }

            return screenPixel.GetPixel(0, 0);
        }
    }
}

现在,显然,您不必使用光标的当前位置,但这是一般的想法。

编辑:

鉴于上述 GetColorAt 函数,您可以像这样以安全、性能友好的方式轮询屏幕上的某个像素:

private void PollPixel(Point location, Color color)
{
    while(true)
    {
        var c = GetColorAt(location);

        if (c.R == color.R && c.G == color.G && c.B == color.B)
        {
            DoAction();
            return;
        }

        // By calling Thread.Sleep() without a parameter, we are signaling to the
        // operating system that we only want to sleep long enough for other
        // applications.  As soon as the other apps yield their CPU time, we will
        // regain control.
        Thread.Sleep()
    }
}

如果需要,您可以将其包装在线程中,或者从控制台应用程序中执行它。 “随心所欲,”我想。

关于c# - 如何读取屏幕像素的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1483928/

相关文章:

c# - 我如何在内存列表中分组?

C# + DirectShow.NET = 简单的网络摄像头访问?

vb.net - VB6/VBA MSFlexGrid 到 VB.NET DataGridView

C# 二维碰撞检测问题

c# - 您如何找到哪个 .NET 项目引用正在传递加载另一个程序集?

c# - 禁用顶级菜单项不会禁用子项,尽管 MSDN 怎么说?

c# - 如何对用户控件中公开的属性使用内置编辑器 - Mask Property Editor Issue

c# - 如何通过 saveFiledialog 将 richboxtext 内容保存到 .txt 文件?

delphi - 将 TCanvas.Pie 坐标转换为 GDI+ DrawPie

c++ - 从资源加载 png 文件(无需 MFC、ATL)