Как найти пиксель определенного цвета в области экранаC#

Место общения программистов C#
Ответить
Anonymous
 Как найти пиксель определенного цвета в области экрана

Сообщение Anonymous »

Я работаю над простым личным проектом, и мне нужно, чтобы он был в состоянии проанализировать каждый пиксель определенной области экрана каждую секунду и печатайте на консоли местоположение всех соответствующих пикселей, которые он находит. Итак, я попробовал это: < /p>
private ScreenCapture screenCapture = new ScreenCapture();
private List targetColors = new List();
private CancellationTokenSource cancellationTokenSource;
private Bitmap screenshot;
private TemporaryForm tempForm;

public frm1()
{
InitializeComponent();
this.DoubleBuffered = true;
Utils.ColorsFound += HandleColorsFound;
}

// FUNCTIONS

private void StartColorMonitoring()
{
cancellationTokenSource?.Cancel();
cancellationTokenSource?.Dispose();
cancellationTokenSource = new CancellationTokenSource();

Task.Factory.StartNew(() =>
{
while (!cancellationTokenSource.Token.IsCancellationRequested)
{
Bitmap screenshot = CaptureScreen(GlobalVariables.MonitoringArea);

Utils.CheckColorsInBackground(screenshot, targetColors, 0, GlobalVariables.MonitoringArea);

screenshot.Dispose();
Thread.Sleep(1000);
}
}, cancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

private void StopColorMonitoring()
{
cancellationTokenSource?.Cancel();
}

private void HandleColorsFound(List
colorLocations)
{
foreach (Point location in colorLocations)
{
Console.WriteLine($"Color found in X: {location.X}, Y: {location.Y}");
}
}

private Bitmap CaptureScreen(Rectangle monitoringArea)
{
Bitmap screenBmp = new Bitmap(monitoringArea.Width, monitoringArea.Height);

using (Graphics screenG = Graphics.FromImage(screenBmp))
{
screenG.CopyFromScreen(monitoringArea.Location, Point.Empty, monitoringArea.Size);
}

return screenBmp;
}

private void button1_Click(object sender, EventArgs e)
{
if (targetColors.Count > 0) { targetColors.Clear(); }

targetColors.Add(GlobalVariables.Color1);
targetColors.Add(GlobalVariables.Color2);
targetColors.Add(GlobalVariables.Color3);

int minX = Math.Min(GlobalVariables.Corner1.X, Math.Min(GlobalVariables.Corner2.X, Math.Min(GlobalVariables.Corner3.X, GlobalVariables.Corner4.X)));
int minY = Math.Min(GlobalVariables.Corner1.Y, Math.Min(GlobalVariables.Corner2.Y, Math.Min(GlobalVariables.Corner3.Y, GlobalVariables.Corner4.Y)));
int maxX = Math.Max(GlobalVariables.Corner1.X, Math.Max(GlobalVariables.Corner2.X, Math.Max(GlobalVariables.Corner3.X, GlobalVariables.Corner4.X)));
int maxY = Math.Max(GlobalVariables.Corner1.Y, Math.Max(GlobalVariables.Corner2.Y, Math.Max(GlobalVariables.Corner3.Y, GlobalVariables.Corner4.Y)));

GlobalVariables.MonitoringArea = new Rectangle(minX, minY, maxX - minX, maxY - minY);

if (tempForm == null)
{
tempForm = new TemporaryForm();
tempForm.Show();
}
else
{
tempForm.Close();
tempForm.Dispose();
tempForm = null;
}

StartColorMonitoring();
}

public class TemporaryForm : Form
{
public TemporaryForm()
{
this.TopMost = true;
this.FormBorderStyle = FormBorderStyle.None;
this.MinimizeBox = this.MaximizeBox = false;
this.MaximizedBounds = GlobalVariables.MonitoringArea;
this.WindowState = FormWindowState.Maximized;
this.TransparencyKey = this.BackColor = Color.Red;

int x = Math.Min(GlobalVariables.Corner1.X, Math.Min(GlobalVariables.Corner2.X, Math.Min(GlobalVariables.Corner3.X, GlobalVariables.Corner4.X)));
int y = Math.Min(GlobalVariables.Corner1.Y, Math.Min(GlobalVariables.Corner2.Y, Math.Min(GlobalVariables.Corner3.Y, GlobalVariables.Corner4.Y)));
this.Location = new Point(x, y);

this.Paint += (sender, e) =>
{
using (Pen yellowPen = new Pen(Color.Yellow, 4))
{
Rectangle borderRect = new Rectangle(0, 0, GlobalVariables.MonitoringArea.Width - 1, GlobalVariables.MonitoringArea.Height - 1);
e.Graphics.DrawRectangle(yellowPen, borderRect);
}
};
}

protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x80000 /* WS_EX_LAYERED */ | 0x20 /* WS_EX_TRANSPARENT */;
return cp;
}
}
}

// CODE ABOVE IS IN Form1.

//CODE UNDER IS IN Utils.cs:

public static event Action ColorsFound;

public static void CheckColorsInBackground(Bitmap screenshot, List targetColors, int tolerance, Rectangle monitoringArea)
{
List colorLocations = new List();
Color pixelColor = new Color();

for (int x = monitoringArea.Left; x = 0 && y < height)
{
pixelColor = screenshot.GetPixel(x, y);
}

foreach (Color targetColor in targetColors)
{
if (ColorMatch(pixelColor, targetColor, tolerance))
{
colorLocations.Add(new Point(x, y));
}
}
}
}

ColorsFound?.Invoke(colorLocations);
}

< /code>
Итак, это вроде как работает, но, например, я выбрал цвет пикселя случайного значка из моего рабочего стола. Затем я перемещаю значок внутри желтых границ временной формы, которая представляет область мониторинга, но цвет не идентифицируется нигде в середине области. Он идентифицируется только в том случае, если я перемещаю значок в верхний левый или нижний левый угол области мониторинга. Есть ли способ сделать пиксельный анализ лучше и быстрее?


Подробнее здесь: https://stackoverflow.com/questions/772 ... the-screen
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»