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);
}
}
}
}
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
GetPixelfunction 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
GetPixelshould use DPI-scaling as well) by callingSetProcessDPIAware: