C# GetPixel 在 Valorant 打开时无法准确获取颜色。

huangapple go评论75阅读模式
英文:

C# GetPixel doesn't give exact color when Valorant is open

问题

当我使用getpixel来捕获屏幕上像素的当前颜色时,它与实际的真实值有轻微变化。

例如,vs studio的背景颜色是31, 31, 31,
但它会给我任何从28到34的值。

只有当Valorant在我的电脑上打开时才会发生这种情况,即使它最小化并不是全屏显示。

以下是代码部分,不需要翻译:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static System.Windows.Forms.LinkLabel;

namespace nameherecool
{
    sealed class Win32
    {
        [DllImport("user32.dll")]
        static public extern bool SetProcessDPIAware();

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("user32.dll")]
        static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("gdi32.dll")]
        static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

        static public System.Drawing.Color GetPixelColor(int x, int y)
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            uint pixel = GetPixel(hdc, x, y);
            ReleaseDC(IntPtr.Zero, hdc);
            Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                         (int)(pixel & 0x0000FF00) >> 8,
                         (int)(pixel & 0x00FF0000) >> 16);
            return color;
        }
    }
    class Program
    {
        static void Main(string[] argfs)
        {
            while (true)
            {
                Console.SetCursorPosition(0, 0);
                Console.WriteLine(Win32.GetPixelColor(0, 0) + "      ");
                Thread.Sleep(500);
            }
        }
    }
}
英文:

When I use getpixel to grab the current color of a pixel from my screen, it has a slight variation from the actual, true value.

For example, the background color of vs studio is 31, 31, 31
but it will give me anything ranging from 28 - 34.

This happens only when Valorant is open on my PC, even if it minimized and not in fullscreen.

Code:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static System.Windows.Forms.LinkLabel;

namespace nameherecool
{
    sealed class Win32
    {
        [DllImport("user32.dll")]
        static public extern bool SetProcessDPIAware();

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hwnd);

        [DllImport("user32.dll")]
        static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("gdi32.dll")]
        static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

        static public System.Drawing.Color GetPixelColor(int x, int y)
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            uint pixel = GetPixel(hdc, x, y);
            ReleaseDC(IntPtr.Zero, hdc);
            Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                         (int)(pixel & 0x0000FF00) >> 8,
                         (int)(pixel & 0x00FF0000) >> 16);
            return color;
        }
    }
    class Program
    {
        static void Main(string[] argfs)
        {
            while (true)
            {
                Console.SetCursorPosition(0, 0);
                Console.WriteLine(Win32.GetPixelColor(0, 0) + "      ");
                Thread.Sleep(500);
            }
        }
    }
}

答案1

得分: 2

The problem with your code is that your system is using DPI-scaling (typical for High Resolution displays to keep things readable). 默认情况下,GDI32中的GetPixel函数不考虑DPI缩放,而光标位置却考虑了DPI缩放。这意味着你没有读取光标下实际的像素。

The solution is simple: Let Windows know your app is DPI-aware (and GetPixel should use DPI-scaling as well) by calling SetProcessDPIAware:

解决方法很简单:通过调用SetProcessDPIAware来告诉Windows你的应用程序是DPI-aware的(并且GetPixel也应该使用DPI缩放):

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace greenbox
{
    sealed class Win32
    {
        [DllImport("user32.dll")]
        static public extern bool SetProcessDPIAware();

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hwnd);
    
        [DllImport("user32.dll")]
        static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("gdi32.dll")]
        static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

        static public System.Drawing.Color GetPixelColor(int x, int y)
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            uint pixel = GetPixel(hdc, x, y);

            ReleaseDC(IntPtr.Zero, hdc);

            Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                                         (int)(pixel & 0x0000FF00) >> 8,
                                         (int)(pixel & 0x00FF0000) >> 16);

            return color;
        }
    }    

    class Program
    {
        static void Main(string[] argfs)
        {
            Win32.SetProcessDPIAware();

            Color newNew;

            while (true)
            {
                newNew = Win32.GetPixelColor(Cursor.Position.X, Cursor.Position.Y);

                Console.SetCursorPosition(0, 0);
                Console.WriteLine(Cursor.Position);
                Console.WriteLine(newNew);
                Thread.Sleep(100);
            }
        }
    }
}

(Note: The code includes both the original text and the translation.)

英文:

The problem with your code is that your system is using DPI-scaling (typical for High Resolution displays to keep things readable).
By default the GetPixel function in GDI32 does not take DPI-scaling into account whereas the cursor-position does.
This means you are not reading the pixel that is actually under the cursor.

The solution is simple: Let Windows know your app is DPI-aware (and GetPixel should use DPI-scaling as well) by calling SetProcessDPIAware:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace greenbox
{
    sealed class Win32
    {
        [DllImport("user32.dll")]
        static public extern bool SetProcessDPIAware();

        [DllImport("user32.dll")]
        static extern IntPtr GetDC(IntPtr hwnd);
    
        [DllImport("user32.dll")]
        static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc);

        [DllImport("gdi32.dll")]
        static extern uint GetPixel(IntPtr hdc, int nXPos, int nYPos);

        static public System.Drawing.Color GetPixelColor(int x, int y)
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            uint pixel = GetPixel(hdc, x, y);

            ReleaseDC(IntPtr.Zero, hdc);

            Color color = Color.FromArgb((int)(pixel & 0x000000FF),
                                         (int)(pixel & 0x0000FF00) >> 8,
                                         (int)(pixel & 0x00FF0000) >> 16);

            return color;
        }
    }    

    class Program
    {
        static void Main(string[] argfs)
        {
            Win32.SetProcessDPIAware();

            Color newNew;

            while (true)
            {
                newNew = Win32.GetPixelColor(Cursor.Position.X, Cursor.Position.Y);

                Console.SetCursorPosition(0, 0);
                Console.WriteLine(Cursor.Position);
                Console.WriteLine(newNew);
                Thread.Sleep(100);
            }
        }
    }
}

huangapple
  • 本文由 发表于 2023年5月21日 11:29:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76298176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定