英文:
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);
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论