В образовательных целях я пытаюсь создать нечто, называемое «детектором цвета».Я пытаюсь создать объекты Array of Point, в которых указанные цвета совпадают в точном месте, чтобы программа могла «щелкнуть» по каждому найденному цвету, который соответствует.Поэтому, если вы хотите, чтобы он обнаруживал, красный, зеленый и желтый, я хочу, чтобы он щелкнул по всем из них в любом порядке, в котором он их находит, если они являются частью указанного массива.
Я хочу, чтобыдобавить ЛЮБОЕ совпадение, которое соответствует массиву шестнадцатеричных цветов, которые я передал в функцию.
Это работает только частично, даже если один и тот же цвет виден в нескольких областях, и не добавляет каждый цвет, который соответствует на экране.в массив.Это оставляет так много цветов, которые соответствуют друг другу.Вдобавок ко всему, это очень и очень медленно до такой степени, что вы думаете, что программа зависла.
Я также хотел бы добавить допуск на цвета, чтобы цвета, близкие к шестнадцатеричному, были приняты.* Чтобы нарисовать быструю картинку, я хочу, чтобы бот нажимал на определенные объекты в инвентаре в игре, которые соответствуют указанным цветам.
Я пытался использовать циклы внутри и снаружи для моего шестнадцатеричного массива в попыткахпопробуйте принудительно заставить программу проверять каждый пиксель для каждого указанного мной цвета.
Вот часть моей функции, которая вызывает его
//Check what the current action is
if (action.ToLower().Contains("find colors and click"))
{
//Make sure to split up the action that looks like this: "Find Colors and Click|#3E5657 #867E7E #957D7C"
string[] splitString = action.Split('|');
//Make an array of Hexadecimal codes
string[] splitHexes = splitString[1].Split(' ');
//Create an Array of Points where SearchPixels detected a match
Point[] points = SearchPixels(splitHexes);
//Make sure it's not empty
if (points != null)
{
//Iterate through each point so we can click at the location of each point where every color we specified was detected even if it was detected many many times
foreach (Point point in points)
{
//Make sure the current point isn't empty
if (!point.IsEmpty)
{
//Move the mouse while updating the status
Status("Moving mouse to " + point.X + " " + point.Y + ". Waiting...");
SetCursorPos(point.X, point.Y);
Status("Moved mouse to " + point.X + " " + point.Y + ". Waiting...");
//Pause the thread for a moment so it doesn't spam click
new System.Threading.ManualResetEvent(false).WaitOne(250);
//Click while updating the status
Status("Clicked. Waiting...");
DoMouseClick();
}
}
}
Вот код, где происходит "волшебство".Я опубликую обе итерации, которые, кажется, не работают, поскольку они пропускают столько совпадающих цветов, либо они даже не обнаруживают их.Я не уверен.
private Point[] SearchPixels(string[] hexcodes)
{
// Take an image from the screen
// Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // Create an empty bitmap with the size of the current screen
Bitmap bitmap = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height); // Create an empty bitmap with the size of all connected screen
Graphics graphics = Graphics.FromImage(bitmap as Image); // Create a new graphics objects that can capture the screen
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); // Screenshot moment → screen content to graphics object
// Create our list of Points that we will eventually return
List<Point> points = new List<Point>();
// Go one to the right and then check from top to bottom every pixel (next round -> go one to right and go down again)
for (int x = 0; x < SystemInformation.VirtualScreen.Width; x++)
{
for (int y = 0; y < SystemInformation.VirtualScreen.Height; y++)
{
// Get the current pixels color
Color currentPixelColor = bitmap.GetPixel(x, y);
// Finally compare the pixels hex color and the desired hex color (if they match we found a pixel)
// Go through each hex code to see if it matches the current pixel as it's one of our desired pixels
foreach (string str in hexcodes)
{
// Get the desired pixel color from the current hexcode
Color desiredPixelColor = ColorTranslator.FromHtml(str);
if (desiredPixelColor == currentPixelColor)
{
// Found Pixel - Now set the location and add it to the array
Point currentPoint = new Point(x, y);
// Make sure it isn't a duplicate.. I wish I could make it not add anything too close either
if (!points.Contains(currentPoint))
{
// Add the current point to the array
points.Add(currentPoint);
}
}
}
}
}
// Return the array
return points.ToArray();
}
Вот вторая версия:
private Point[] SearchPixels(string[] hexcodes)
{
// Take an image from the screen
// Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // Create an empty bitmap with the size of the current screen
Bitmap bitmap = new Bitmap(SystemInformation.VirtualScreen.Width, SystemInformation.VirtualScreen.Height); // Create an empty bitmap with the size of all connected screen
Graphics graphics = Graphics.FromImage(bitmap as Image); // Create a new graphics objects that can capture the screen
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); // Screenshot moment → screen content to graphics object
// Create our list of Points that we will eventually return
List<Point> points = new List<Point>();
// Go through each hex code to see if it matches the current pixel as it's one of our desired pixels
foreach (string str in hexcodes)
{
// Get the desired pixel color from the current hexcode
Color desiredPixelColor = ColorTranslator.FromHtml(str);
// Go one to the right and then check from top to bottom every pixel (next round -> go one to right and go down again)
for (int x = 0; x < SystemInformation.VirtualScreen.Width; x++)
{
for (int y = 0; y < SystemInformation.VirtualScreen.Height; y++)
{
// Get the current pixels color
Color currentPixelColor = bitmap.GetPixel(x, y);
// Finally compare the pixels hex color and the desired hex color (if they match we found a pixel)
// Go through each hex code to see if it matches the current pixel as it's one of our desired pixels
if (desiredPixelColor == currentPixelColor)
{
// Found Pixel - Now set the location and add it to the array
Point currentPoint = new Point(x, y);
// Make sure it isn't a duplicate.. I wish I could make it not add anything too close either
if (!points.Contains(currentPoint))
{
// Add the current point to the array
points.Add(currentPoint);
}
}
}
}
// Return the array
return points.ToArray();
}
Я ожидаю, что бот обнаружит и вернет каждую точку на экране, соответствующую цветулюбого шестнадцатеричного цвета в массиве шестнадцатеричных я предоставил.Это просто не делает этого.Это соответствует, может быть, 1-5, а затем сдается.Иногда он обнаруживает только один цвет из трех представленных, а иногда только два.Например: даже если в инвентаре есть 28 объектов одного цвета, он может только найти и предоставить массив из 8 точек вместо 28.
Я также хочу, чтобы эти координаты действительно быстро находились какЯ не хочу, чтобы программа работала медленно.
Я очень расстроен и благодарю вас за вашу помощь.
Редактировать: Я действительно много раз отлаживал свой код.