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);
}
}
}
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()
}
}
Color GetColorAt(int x, int y)
{
Bitmap bmp = new Bitmap(1, 1);
Rectangle bounds = new Rectangle(x, y, 1, 1);
using (Graphics g = Graphics.FromImage(bmp))
g.CopyFromScreen(bounds.Location, Point.Empty, bounds.Size);
return bmp.GetPixel(0, 0);
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
[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);
Thread t;
int x, y;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
x = 20;
y = 50;
t = new Thread(update);
t.Start();
}
private void update()
{
Bitmap screenCopy = new Bitmap(1, 1);
using (Graphics gdest = Graphics.FromImage(screenCopy))
{
while (true)
{
//g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(256, 256));
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero))
{
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, 1, 1, hSrcDC, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
Color c = Color.FromArgb(screenCopy.GetPixel(0, 0).ToArgb());
label1.ForeColor = c;
}
}
}
}
6条答案
按热度按时间eoigrqb61#
这是最有效的:它在光标所在的位置抓取一个像素,并且不依赖于只有一个监视器。
现在,显然,您不必使用光标的当前位置,但这是一般的想法。
编辑:
给定上面的
GetColorAt
函数,你可以用一种安全、性能友好的方式轮询屏幕上的某个像素,如下所示:如果需要,您可以将其 Package 在Thread中,或者从Console应用程序中执行它。
xxls0lw82#
这里的大多数答案都使用了该像素的相同来源(桌面dc)。
键功能为
GetPixel
。我想这是最干净最快捷的方式。
备注:
如果您在Windows上修改了“显示设置”中的默认文本大小,以提高高分辨率显示器的可读性,则需要以相同的方式调整GetPixel()的坐标参数。例如,如果在Windows 7上光标位置为(x,y),文本大小为150%,则需要调用GetPixel(x1.5,y1.5)来获取光标下像素的颜色。
0qx6xfy63#
此函数更短,使用
System.Drawing
也能达到相同的结果,但不使用Pinvoke。mznpcxlj4#
请检查这两个不同的功能,我用在我以前的项目之一:
1)此函数可拍摄桌面的快照
2)此函数采用输入图像,并计算给定像素范围的RGB平均值。
这两个函数一起可能会解决你的问题。快乐编码:)
EDIT:请注意,GetPixel是一个非常慢的函数。在使用它之前,我会三思而后行。
sczxawaw5#
据我所知最简单的办法是:
1.查看位图并获取像素颜色
编辑
可能没有办法“等待”直到像素变成某种颜色。你的程序可能不得不经常循环检查它,直到它看到颜色。
例如:
编辑2
下面是一些可以修改的示例代码。这段代码只是根据给定像素中的当前颜色更改标签的颜色。这段代码避免了上面提到的句柄泄漏。
}
qyuhtwio6#
这条线使用约10 ms。