I've tried open source projects such as this one however it doesn't seem to work at all for me. I then attempted to write my own algorithm like so (tolerance isn't being used yet).
public static Rectangle ImageSearch(Bitmap ToSearch, Bitmap ToFind, int Tolerance, double MinPercent) {
Rectangle ReturnValue = Rectangle.Empty;
BitmapData ToSearchData = ToSearch.LockBits(new Rectangle(0, 0, ToSearch.Width, ToSearch.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
BitmapData ToFindData = ToFind.LockBits(new Rectangle(0, 0, ToFind.Width, ToFind.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
IntPtr ToSearchScan0 = ToSearchData.Scan0;
IntPtr ToFindScan0 = ToFindData.Scan0;
int PixelWidth = 3; // 3 since 24 bits per pixel format
int ToSearchStride = ToSearchData.Stride;
int ToSearchPadding = ToSearchStride - (ToSearch.Width * PixelWidth);
int ToFindStride = ToFindData.Stride;
int ToFindPadding = ToFindStride - (ToFind.Width * PixelWidth);
unsafe {
byte *ToSearchPixelArray = (byte*)(void*)ToSearchData.Scan0;
byte *ToFindPixelArray = (byte*)(void*)ToFindData.Scan0;
byte sB, sG, sR, fB, fG, fR;
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
for (int sY = 0; sY < ToSearch.Height; sY++) {
for (int sX = 0; sX < ToSearch.Width * PixelWidth; sX += PixelWidth) {
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
Console.WriteLine("found possible match");
byte *ToSearchBackup = ToSearchPixelArray;
byte *ToFindBackup = ToFindPixelArray;
int MatchedPixels = 0;
for (int fY = 0; fY < ToFind.Height; fY++) {
for (int fX = 0; fX < ToFind.Width * PixelWidth; fX += PixelWidth) {
fB = ToFindPixelArray[0];
fG = ToFindPixelArray[1];
fR = ToFindPixelArray[2];
sB = ToSearchPixelArray[0];
sG = ToSearchPixelArray[1];
sR = ToSearchPixelArray[2];
if (sB == fB && sG == fG && sR == fR) {
++MatchedPixels;
} else {
ToSearchPixelArray = ToSearchBackup;
ToFindPixelArray = ToFindBackup;
// this is the best way to break a nested loop in C#
fX = int.MaxValue;
fY = int.MaxValue;
}
}
ToSearchPixelArray += ToSearchStride - sX;
ToFindPixelArray += ToFindPadding;
}
if (MatchedPixels / (ToFind.Width * ToFind.Height) >= MinPercent) {
ReturnValue.X = (int)(sX / 3);
ReturnValue.Y = sY;
ReturnValue.Width = ToFind.Width;
ReturnValue.Height = ToFind.Height;
// this is the best way to break a nested loop in C#
sX = int.MaxValue;
sY = int.MaxValue;
}
}
}
ToSearchPixelArray += ToSearchPadding;
}
}
ToSearch.UnlockBits(ToSearchData);
ToFind.UnlockBits(ToFindData);
return ReturnValue;
}
But not even this will detect a screenshot I take of the exact image I'm searching through. Please do not suggest things such as Emgu, I'm using this in a commercial application and cannot afford to purchase a license from any GNU licensed projects (I'm not open sourcing the project either).