示例#1
0
        protected async Task <List <Rectangle> > _findSubimagesMultithreaded(DirectBitmap small, byte margin, ImageSearchingOptions opts)
        {
            var xy    = MathHelper.CalculateTableForGrids(opts.Threads);
            var rects = this.Area.Split(xy.X, xy.Y).ToArray();
            var token = new cancelToken();
            DataflowNotifier <List <Rectangle> > df = null;
            AsyncManualResetEvent res = new AsyncManualResetEvent(false);

            if (opts.NumberOfResults > 0)   //limit search!
            {
                df = new DataflowNotifier <List <Rectangle> >(r => {
                    var @out = !(df.Collection.Count >= opts.NumberOfResults);
                    if (@out == false)   //has reached limit
                    {
                        token.Cancel();
                        res.Set();
                    }
                    return(@out);
                }, true);
            }
            else
            {
                df = new DataflowNotifier <List <Rectangle> >(true);
            }
            Debugging.Restart();
            //Debugging.Print("Ready to fire");
            int i = 0;

            Task[] tasks = opts.IgnoreAlphaPixels && small.Map != null
                ? rects.Select(r => Pool.Run(() => _findImageAlpha(small, r, small.Map.Ranges, margin, token, opts)).AndThen(t => df.Set(t))).ToArray()
                : rects.Select(r => Pool.Run(() => _findImage(small, r, margin, token, opts)).AndThen(t => df.Set(t))).ToArray();

            await Task.WhenAny(Task.WhenAll(tasks), res.WaitAsync());

            //Debugging.Print("Has Ended");
            return(df.Collection.ToArray().SelectMany(l => l).ToList());
        }
示例#2
0
        protected virtual unsafe List <Rectangle> _findImage(DirectBitmap small, Rectangle area, int margin, cancelToken token, ImageSearchingOptions opts)
        {
            opts = opts ?? ImageSearchingOptions.Default;
            var @out       = new List <Rectangle>(0);
            int jump_small = small.PixelSize;
            int jump_large = this.PixelSize;

            byte *scan_large = (byte *)this._scan0;  //[largeX+ smallX, largeY+ smallY];
            byte *scan_small = (byte *)small._scan0; //[smallX, smallY];
            int   c, smallX = 0, smallY = 0, pix = 0;
            byte *s, l;

            //Debugging.Print($"{Thread.CurrentThread.ManagedThreadId} has started");
            for (int largeY = area.Y; largeY < area.Y + area.Height; largeY++)
            {
                if (token.cancel) //here so it wont impact performance so bad
                {
                    return(@out);
                }
                for (int largeX = area.X; largeX < area.X + area.Width; largeX++)
                {
                    for (smallY = 0; smallY < small.Height; smallY++)
                    {
                        for (smallX = 0; smallX < small.Width; smallX++)
                        {
                            l = scan_large + (((largeX + smallX) + (largeY + smallY) * this.Width) * jump_large);
                            s = scan_small + (smallX + smallY * small.Width) * jump_small;
                            for (pix = 0; pix < 3; pix++)
                            {
                                c = l[pix] - s[pix]; //c==margin
                                if (c > margin || c < -margin)
                                {
                                    goto nextLoop;
                                }
                            }
                        }
                    }
                    //If all the pixels match up, then return true and change Point location to the top left co-ordinates where it was found
                    @out.Add(new Rectangle(largeX, largeY, small.Width, small.Height));
                    Debugging.Print($"{Thread.CurrentThread.ManagedThreadId} has found: {new Rectangle(largeX, largeY, small.Width, small.Height)}");
                    if (opts.NumberOfResults != -1 && @out.Count >= opts.NumberOfResults)
                    {
                        return(@out);
                    }
                    //Go to next pixel on large image
nextLoop:
                    ;
                }
            }
            //Return false if image is not found, and set an empty point
/*            location = Point.Empty;*/
            //Debugging.Print($"{Thread.CurrentThread.ManagedThreadId} has finished");
            return(@out);
        }