Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#获取屏幕上某点颜色的有效方法_C#_.net_Colors_Screen - Fatal编程技术网

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声明
注2:


据我所知,你最好直接使用Graphics.CopyFromScreen,因为它将使用BitBlt。这在我看来更安全,麻烦更少。

为什么要使用
Format16bppArgb1555
?哪一行会引发异常?我尝试过使用和不使用,我只使用了它,因为我只需要8位的颜色精度。我会更新帖子中的颜色精度h line抛出异常。
screenPixel
是类成员还是局部变量?在链接的解决方案中,它是一个可重用的类成员(希望在表单的Dispose方法中被释放).BTW:
使用
已经调用了
Dispose
,为什么要显式调用它。尝试删除它们…只需在.NET中查找滴管示例并根据需要对其进行更改:您能告诉我
(int)的位置吗0x00CC0020
值来自?是对bitBlt和枚举TernaryRasterOperations的描述。因为我认为它丢失了,所以我复制了
SRCCOPY
的值。我真傻!请注意,您可能需要使用
int bpp=Screen.PrimaryScreen.BitsPerPixel;
来确定屏幕的颜色深度。