Rectangle?workThread(WorkThreadData workThreadData, Queue <Rectangle> workQueue) { while (true) { Rectangle taskZone; lock (workQueue) { if (workQueue.Count > 0) { taskZone = workQueue.Dequeue(); } else { break; } } var result = searchNeedle(workThreadData, taskZone); if (result.HasValue) { workQueue.Clear(); return(result.Value); } } return(null); }
Rectangle?matchBitmaps(Bitmap haystack, Bitmap needle, Rectangle searchZone, float threshold) { Rectangle?found = null; var haystackImageData = new ImageData(haystack); var needleImageData = new ImageData(needle); var workQueue = prepareWorkQueue(haystack.Size, needle.Size, searchZone); var taskList = new List <Task <Rectangle?> >(); var workThreadData = new WorkThreadData { HaystackImageData = haystackImageData, NeedleImageData = needleImageData, Threshold = threshold }; for (int t = 0; t < ThreadCount; t++) { taskList.Add(new Task <Rectangle?>(delegate() { return(workThread(workThreadData, workQueue)); })); } haystackImageData.Lock(); needleImageData.Lock(); taskList.ForEach(task => task.Start()); Task.WaitAll(taskList.ToArray()); foreach (var task in taskList) { var result = task.Result; if (result.HasValue) { found = result.Value; } } haystackImageData.Unlock(); needleImageData.Unlock(); return(found); }
Rectangle?searchNeedle(WorkThreadData workThreadData, Rectangle searchZone) { var haystackImageData = workThreadData.HaystackImageData; var needleImageData = workThreadData.NeedleImageData; var threshold = workThreadData.Threshold; var resultFound = false; for (int sY = searchZone.Y; sY < searchZone.Y + searchZone.Height; sY++) { for (int sX = searchZone.X; sX < searchZone.X + searchZone.Width; sX++) { for (int tY = 0; tY < searchZone.Height; tY++) { for (int tX = 0; tX < searchZone.Width; tX++) { var tPixel = needleImageData.GetPixel(tX, tY); var sPixel = haystackImageData.GetPixel(sX + tX, sY + tY); resultFound = compareColors(tPixel, sPixel, threshold); if (!resultFound) { break; } } if (!resultFound) { break; } } if (resultFound) { return(new Rectangle(sX, sY, needleImageData.Bitmap.Width, needleImageData.Bitmap.Height)); } } } return(null); }