When I use the following code, it takes around 3-5 seconds before the loop is done if the image I am searching for in the image is not found. While this is searching the rest of the program is paused, my timers gets out of sync and it looks like the program freezes for a few seconds. The images are not very big, “printscreen” is around 344×354 and “Ok” is around 15×7. I know it is because of the for-loops, but is there a better way to do this or can I runt his part of the program besides the rest of the program in some way, so the program won’t freeze for a few seconds.
// Ok is the image I am searching for.
// printscreen is the image I am searching in.
Bitmap Ok = new Bitmap(Properties.Resources.popupok1);
int Count = 0;
for (int x = 0; x < printscreen.Width; x++)
{
for (int y = 0; y < printscreen.Height; y++)
{
Count = 0;
if (printscreen.GetPixel(x, y) == Ok.GetPixel(0, 0) &&
printscreen.GetPixel(x + 1, y) == Ok.GetPixel(1, 0))
{
for (int OkX = 0; OkX <= Ok.Width; OkX++)
{
for (int OkY = 0; OkY <= Ok.Height; OkY++)
{
try
{
if (printscreen.GetPixel(x + OkX, y + OkY) != Ok.GetPixel(OkX, OkY))
{
OkX = Ok.Width;
OkY = Ok.Height;
}
else
{
Count += 1;
}
if (Count == 105)
{
X = x;
Y = y;
OkX = Ok.Width;
OkY = Ok.Height;
x = printscreen.Width - 1;
y = printscreen.Height - 1;
Console.Add("Ok button found.");
Console.Add("");
ConsoleUpdate();
}
}
catch { }
}
}
}
}
}
The performance issue is caused by GetPixels/SetPixels, which is an extraordinarily slow way to access the data in an .NET Bitmap. Instead, I would look into the Bitmap.LockBits method to get a pointer to the bitmap and manipulate data directly. It will be an order of magnitude faster.
See MSDN:
If you want to go even faster rather than copy the array out, manipulate it and copy it back, you can operate on the bitmap in place using an unsafe pointer. In this case, the inner part would change as follows:
Just take care to note the PixelFormat of the bitmap. The example above assumes its 24 bits per pixel BGR. In actual fact many bitmaps are BGRA (32bits per pixel) so you will need to modify four bytes for Blue, Gree, Red, Alpha in that order per pixel.