确定winforms应用程序中像素的颜色

我希望能够在屏幕上的某个点确定winform的背景颜色,因此我可以根据特定的颜色采取一些措施。 可悲的是,System.Drawing库似乎没有指定一个允许我这样做的方法。

那么我应该如何确定某一点的颜色?

使用:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Drawing; namespace ColorUnderCursor { class CursorColor { [DllImport("gdi32")] public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos); [DllImport("user32.dll", CharSet = CharSet.Auto)] public static extern bool GetCursorPos(out POINT pt); [DllImport("User32.dll", CharSet = CharSet.Auto)] public static extern IntPtr GetWindowDC(IntPtr hWnd); ///  /// Gets the System.Drawing.Color from under the mouse cursor. ///  /// The color value. public static Color Get() { IntPtr dc = GetWindowDC(IntPtr.Zero); POINT p; GetCursorPos(out p); long color = GetPixel(dc, pX, pY); Color cc = Color.FromArgb((int)color); return Color.FromArgb(cc.B, cc.G, cc.R); } } [StructLayout(LayoutKind.Sequential)] public struct POINT { public int X; public int Y; public POINT(int x, int y) { X = x; Y = y; } } } 

假设您希望远离Win32 API,可以使用Graphics.CopyFromScreen()将屏幕内容绘制到Bitmap对象。 从那里,您只需要使用Bitmap.GetPixel()来检索具有正确颜色的Color对象。

以下是一些可用于检索完整桌面的代码(适用于多个监视器):

 public Image GetScreenshot() { int screenWidth = Convert.ToInt32(System.Windows.SystemParameters.VirtualScreenWidth); int screenHeight = Convert.ToInt32(SystemParameters.VirtualScreenHeight); int screenLeft = Convert.ToInt32(SystemParameters.VirtualScreenLeft); int screenTop = Convert.ToInt32(SystemParameters.VirtualScreenTop); Image imgScreen = new Bitmap(screenWidth, screenHeight); using (Bitmap bmp = new Bitmap(screenWidth, screenHeight, PixelFormat.Format32bppArgb)) using (Graphics g = Graphics.FromImage(bmp)) using (Graphics gr = Graphics.FromImage(imgScreen)) { g.CopyFromScreen(screenLeft, screenTop, 0, 0, new Size(screenWidth, screenHeight)); gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; gr.DrawImage(bmp, new Rectangle(0, 0, screenWidth, screenHeight)); } return imgScreen; } 

这与已经提供的其他答案略有不同,因为您只是声明要确定“颜色”,但没有明确说明您想要RGB值。

这种区别是必要的,因为可能存在人眼难以察觉的颜色变化。 例如,假设您有兴趣检测颜色“蓝色”。 值(5,5,240)和(10,10,255)仅与(0,0,255)非常微妙地不同。 事实上,差异是如此微妙,你需要并排比较颜色样本,告诉他们分开,即使这样,它取决于你的显示器的质量。 它们在我的桌面显示器上略有不同,但在我的笔记本电脑上难以区分。 长话短说,RGB值是决定颜色的坏方法。

有许多方法可以帮助计算颜色之间的差异,最常见的是Delta-E方法。 但是,如果你只想要一个快速而肮脏的方法,这可能会过度杀戮。 将RGB空间转换为HSV并使用色调差异来确定颜色。 修改阿门的例子,你会得到以下结果:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Drawing; class CursorHue { [DllImport("gdi32")] public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos); public static float GetHue(Point p) { long color = GetPixel(dc, pX, pY); Color cc = Color.FromArgb((int)color); return cc.GetHue(); } } 

纯蓝色的色调值为240.前面的例子(5,5,240)和(10,10,255)都具有240的色调。这是个好消息,因为这意味着色调是一种相当宽容的度量到RGB差异,差异也很快计算(即只取色调值的绝对差值)。 在这一点上,我们还应该引入另一个参数来控制可接受的色差容差。 15度的色调容差将使系统相当稳健。

这是用于比较两种颜色以确定它们是否可接受相似的示例代码

 public static bool AreSimilar(Color c1, Color c2, float tolerance = 15f) { return Math.Abs(c1.GetHue() - c2.GetHue() <= tolerance; } 

有关其工作原理的更深入解释,请参阅此维基百科有关HSV色彩空间的文章 。