C#获取屏幕上某点颜色的有效方法
我有一个工作方法,但它是相当资源密集型,我正在寻找一个更好的方式。在回答类似问题时,建议运行下面的代码 但是,运行所述代码会产生一个C#获取屏幕上某点颜色的有效方法,c#,.net,colors,screen,C#,.net,Colors,Screen,我有一个工作方法,但它是相当资源密集型,我正在寻找一个更好的方式。在回答类似问题时,建议运行下面的代码 但是,运行所述代码会产生一个System.OutOfMemoryException 使用(Graphics gdest=Graphics.FromImage(screenPixel)){ 当前代码: Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format16bppArgb1555); using (Graphics gdest = Gr
System.OutOfMemoryException
使用(Graphics gdest=Graphics.FromImage(screenPixel)){
当前代码:
Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format16bppArgb1555);
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, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
return screenPixel.GetPixel(0, 0);
编辑:
好的,我已经用下面的代码修复了上面的问题。但是现在我只返回黑色(0,0,0)
this.screenPixel = new Bitmap(1, 1, PixelFormat.Format16bppRgb555);
using (Graphics gdest = Graphics.FromImage(this.screenPixel)) {
using (Graphics gsrc = Graphics.FromHwnd(IntPtr.Zero)) {
IntPtr hSrcDC = gsrc.GetHdc();
IntPtr hDC = gdest.GetHdc();
int retval = BitBlt(hDC, 0, 0, width, height, hSrcDC, x, y, (int)CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
Color result = screenPixel.GetPixel(0, 0);
Console.WriteLine(result.R + " " + result.G + " " + result.B);
GC.SuppressFinalize(this.screenPixel);
this.screenPixel.Dispose();
return result;
这似乎在这里起作用:
using System.Runtime.InteropServices;
//...
[DllImport("gdi32.dll")]
public static extern int BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjSource, int nXSrc, int nYSrc, int dwRop);
//..
Bitmap screenPixel = new Bitmap(1, 1, PixelFormat.Format32bppRgb);
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, x, y,
(int) CopyPixelOperation.SourceCopy);
gdest.ReleaseHdc();
gsrc.ReleaseHdc();
}
}
Color c = screenPixel.GetPixel(0, 0);
return c;
注1:
- 我已更改像素格式以匹配我的屏幕
- 我已经修改了BitBlt声明
据我所知,你最好直接使用Graphics.CopyFromScreen,因为它将使用BitBlt。这在我看来更安全,麻烦更少。为什么要使用
Format16bppArgb1555
?哪一行会引发异常?我尝试过使用和不使用,我只使用了它,因为我只需要8位的颜色精度。我会更新帖子中的颜色精度h line抛出异常。screenPixel
是类成员还是局部变量?在链接的解决方案中,它是一个可重用的类成员(希望在表单的Dispose方法中被释放).BTW:使用
已经调用了Dispose
,为什么要显式调用它。尝试删除它们…只需在.NET中查找滴管示例并根据需要对其进行更改:您能告诉我(int)的位置吗0x00CC0020
值来自?是对bitBlt和枚举TernaryRasterOperations的描述。因为我认为它丢失了,所以我复制了SRCCOPY
的值。我真傻!请注意,您可能需要使用int bpp=Screen.PrimaryScreen.BitsPerPixel;
来确定屏幕的颜色深度。