我希望能夠確定屏幕上特定點處的Winform的背景顏色,因此我可以根據該特定顏色採取一些操作。可悲的是,System.Drawing庫似乎沒有指定一種方法,使我能夠這樣做。確定WinForms應用程序中像素的顏色
我應該如何確定某一點的顏色?
我希望能夠確定屏幕上特定點處的Winform的背景顏色,因此我可以根據該特定顏色採取一些操作。可悲的是,System.Drawing庫似乎沒有指定一種方法,使我能夠這樣做。確定WinForms應用程序中像素的顏色
我應該如何確定某一點的顏色?
使用:
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;
}
}
}
這是不完整的,其中是你定義的'dc'變量致電GetPixel? – fuaaark 2012-04-12 09:27:51
檢查更新... – 2012-04-12 09:28:35
+1,歡迎 – 2012-04-12 11:42:05
假設您想要遠離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, 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色彩空間這個維基百科article。
可能的重複http://stackoverflow.com/questions/1483928/how-to-read-the-color-of-a-screen-pixel – Marco 2012-04-12 09:17:25