我希望能够确定在屏幕上的某一个点一个winform的backgroundColor,所以取决于特定的颜色,我可以采取一些行动。 可悲的是System.Drawing中图书馆似乎并没有规定,使我这样做的方法。
我应该如何再确定在某一点的颜色?
我希望能够确定在屏幕上的某一个点一个winform的backgroundColor,所以取决于特定的颜色,我可以采取一些行动。 可悲的是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);
/// <summary>
/// Gets the System.Drawing.Color from under the mouse cursor.
/// </summary>
/// <returns>The color value.</returns>
public static Color Get()
{
IntPtr dc = GetWindowDC(IntPtr.Zero);
POINT p;
GetCursorPos(out p);
long color = GetPixel(dc, p.X, p.Y);
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值是决定颜色的好方法。
有许多方法计算的颜色,最常见的是三角洲-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, p.X, p.Y);
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色彩空间。