コード例 #1
0
        private Point FindOuter(Bitmap bmp, int x, int y, int step = 1, int searchWidth = 20)
        {
            var delta = step < 0 ? -1 : 1;
            var max   = delta > 0 ? bmp.Width - x : x;

            if (searchWidth > max)
            {
                searchWidth = max;
            }

            int target;
            var rect = new Rectangle(0, y, bmp.Width, 1);

            using (var data = new LockData(bmp, rect))
            {
                target = Helper.Range(1, searchWidth, Math.Abs(step))
                         .Select(dx => x + delta * dx)
                         .Where(dx => data.IsBlackAt(dx))
                         .DefaultIfEmpty(-1)
                         .First();

                // if possible, move slightly to the left or right to get to the
                // middle of the frame
                while (data.IsBlackAt(target + delta))
                {
                    target += delta;
                }
            }

            return(new Point(target, y));
        }
コード例 #2
0
        private Rectangle SelectFrame(Bitmap bmp, Point p)
        {
            var skip = 0;

            var top    = 0;
            var bottom = 0;

            var rect = new Rectangle(p.X, 0, 1, bmp.Height);

            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(0, p.Y))
                {
                    return(new Rectangle());
                }

                top = Helper.Range(p.Y, 0, -1)
                      .TakeWhile(y => data.IsBlackAt(0, y) ||
                                 skip++ < MaxSkip)
                      .Last(y => data.IsBlackAt(0, y));

                skip   = 0;
                bottom = Helper.Range(p.Y, bmp.Height - 1)
                         .TakeWhile(y => data.IsBlackAt(0, y) ||
                                    skip++ < MaxSkip)
                         .Last(y => data.IsBlackAt(0, y));
            }

            var border = FindBorder(bmp, new Point(p.X, bottom));
            var left   = border.Left;

            // verify the left border is indeed black
            var leftRect = new Rectangle(left, 0, 1, bmp.Height);

            using (var data = new LockData(bmp, leftRect))
            {
                if (!data.IsColumnBlack(0, top, bottom, MaxSkip))
                {
                    return(new Rectangle());
                }
            }

            return(new Rectangle(left, top, border.Width, bottom - top + 1));
        }
コード例 #3
0
        private Rectangle FindBorder(Bitmap bmp, Point p)
        {
            int left, right;
            var rect = new Rectangle(0, p.Y, bmp.Width, 1);

            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(p.X))
                {
                    return(new Rectangle());
                }

                left = Helper.Range(p.X, 0, -1)
                       .TakeWhile(x => data.IsBlackAt(x))
                       .Last();

                right = Helper.Range(p.X, bmp.Width - 1)
                        .TakeWhile(x => data.IsBlackAt(x))
                        .Last();
            }

            return(new Rectangle(left, p.Y, right - left + 1, 0));
        }
コード例 #4
0
        unsafe private static Bitmap CopyName(Bitmap source, Bitmap mapper, Rectangle srcRect)
        {
            var w    = srcRect.Width;
            var h    = srcRect.Height;
            var name = new Bitmap(w, h, source.PixelFormat);

            var destRect = new Rectangle(0, 0, w, h);

            using (var dest = new LockData(name, destRect, ImageLockMode.ReadWrite))
                using (var src = new LockData(source, srcRect))
                    using (var map = new LockData(mapper, srcRect))
                    {
                        for (var x = 0; x < w; x++)
                        {
                            for (var y = 0; y < h; y++)
                            {
                                if (map.IsBlackAt(x, y))
                                {
                                    continue;
                                }

                                // copy the matching and all neighboring pixels to get
                                // some kind of font anti-aliasing
                                var points = from dx in Helper.Range(-1, 1)
                                             from dy in Helper.Range(-1, 1)
                                             let fy                   = y + dy
                                                               let fx = x + dx
                                                                        where fy >= 0 && fy < h && fx >= 0 && fx < w
                                                                        select new { dx, dy };

                                foreach (var d in points)
                                {
                                    var dx = x + d.dx;
                                    var dy = y + d.dy;
                                    dest[dx, dy] = src[dx, dy];
                                }
                            }
                        }
                    }

            return(name);
        }
コード例 #5
0
        unsafe private static void TraverseFill(LockData data, int x, int y)
        {
            if (x < 0 || x >= data.Width)
            {
                return;
            }
            if (y < 0 || y >= data.Height)
            {
                return;
            }
            if (data.IsBlackAt(x, y))
            {
                return;
            }

            data.SetBlack(x, y);

            TraverseFill(data, x - 1, y);
            TraverseFill(data, x + 1, y);
            TraverseFill(data, x, y - 1);
            TraverseFill(data, x, y + 1);
        }
コード例 #6
0
        private Rectangle SelectFrame(Bitmap bmp, Point p)
        {
            var skip = 0;

            var top = 0;
            var bottom = 0;

            var rect = new Rectangle(p.X, 0, 1, bmp.Height);
            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(0, p.Y)) return new Rectangle();

                top = Helper.Range(p.Y, 0, -1)
                        .TakeWhile(y => data.IsBlackAt(0, y) ||
                            skip++ < MaxSkip)
                        .Last(y => data.IsBlackAt(0, y));

                skip = 0;
                bottom = Helper.Range(p.Y, bmp.Height - 1)
                        .TakeWhile(y => data.IsBlackAt(0, y) ||
                            skip++ < MaxSkip)
                        .Last(y => data.IsBlackAt(0, y));
            }

            var border = FindBorder(bmp, new Point(p.X, bottom));
            var left = border.Left;

            // verify the left border is indeed black
            var leftRect = new Rectangle(left, 0, 1, bmp.Height);
            using (var data = new LockData(bmp, leftRect))
            {
                if (!data.IsColumnBlack(0, top, bottom, MaxSkip))
                    return new Rectangle();
            }

            return new Rectangle(left, top, border.Width, bottom - top + 1);
        }
コード例 #7
0
        private List <Point> FindBlackSquares(Bitmap bmp, IEnumerable <int> horizontal,
                                              IEnumerable <int> vertical, int size = 5)
        {
            var black = new List <Point>();
            var w     = bmp.Width;
            var h     = bmp.Height;

            using (var data = new LockData(bmp))
            {
                foreach (var y in vertical)
                {
                    foreach (var x in horizontal)
                    {
                        if (Helper.Range(-size, size).All(dx =>
                                                          Helper.Range(-size, size).All(dy =>
                                                                                        x + dx < w && x + dx >= 0 &&
                                                                                        y + dy < h && y + dy >= 0 &&
                                                                                        data.IsBlackAt(x + dx, y + dy)
                                                                                        )))
                        {
                            black.Add(new Point(x, y));
                            // since we move outwards from the cursor, we can safely
                            // break here without risking not to hit the actual item
                            // frame
                            break;
                        }
                    }
                }
            }

            return(black);
        }
コード例 #8
0
        private Point FindOuter(Bitmap bmp, int x, int y, int step = 1, int searchWidth = 20)
        {
            var delta = step < 0 ? -1 : 1;
            var max = delta > 0 ? bmp.Width - x : x;
            if (searchWidth > max) searchWidth = max;

            int target;
            var rect = new Rectangle(0, y, bmp.Width, 1);
            using (var data = new LockData(bmp, rect))
            {
                target = Helper.Range(1, searchWidth, Math.Abs(step))
                    .Select(dx => x + delta * dx)
                    .Where(dx => data.IsBlackAt(dx))
                    .DefaultIfEmpty(-1)
                    .First();

                // if possible, move slightly to the left or right to get to the
                // middle of the frame
                while (data.IsBlackAt(target + delta))
                    target += delta;
            }

            return new Point(target, y);
        }
コード例 #9
0
        private Rectangle FindBorder(Bitmap bmp, Point p)
        {
            int left, right;
            var rect = new Rectangle(0, p.Y, bmp.Width, 1);
            using (var data = new LockData(bmp, rect))
            {
                if (!data.IsBlackAt(p.X)) return new Rectangle();

                left = Helper.Range(p.X, 0, -1)
                    .TakeWhile(x => data.IsBlackAt(x))
                    .Last();

                right = Helper.Range(p.X, bmp.Width - 1)
                    .TakeWhile(x => data.IsBlackAt(x))
                    .Last();
            }

            return new Rectangle(left, p.Y, right - left + 1, 0);
        }
コード例 #10
0
        private List<Point> FindBlackSquares(Bitmap bmp, IEnumerable<int> horizontal,
            IEnumerable<int> vertical, int size = 5)
        {
            var black = new List<Point>();
            var w = bmp.Width;
            var h = bmp.Height;

            using (var data = new LockData(bmp))
            {
                foreach (var y in vertical)
                {
                    foreach (var x in horizontal)
                    {
                        if (Helper.Range(-size, size).All(dx =>
                            Helper.Range(-size, size).All(dy =>
                                x + dx < w && x + dx >= 0 &&
                                y + dy < h && y + dy >= 0 &&
                                data.IsBlackAt(x + dx, y + dy)
                            )))
                        {
                            black.Add(new Point(x, y));
                            // since we move outwards from the cursor, we can safely
                            // break here without risking not to hit the actual item
                            // frame
                            break;
                        }
                    }
                }
            }

            return black;
        }
コード例 #11
0
        private static unsafe void TraverseFill(LockData data, int x, int y)
        {
            if (x < 0 || x >= data.Width) return;
            if (y < 0 || y >= data.Height) return;
            if (data.IsBlackAt(x, y)) return;

            data.SetBlack(x, y);

            TraverseFill(data, x - 1, y);
            TraverseFill(data, x + 1, y);
            TraverseFill(data, x, y - 1);
            TraverseFill(data, x, y + 1);
        }
コード例 #12
0
        private static unsafe Bitmap CopyName(Bitmap source, Bitmap mapper, Rectangle srcRect)
        {
            var w = srcRect.Width;
            var h = srcRect.Height;
            var name = new Bitmap(w, h, source.PixelFormat);

            var destRect = new Rectangle(0, 0, w, h);

            using (var dest = new LockData(name, destRect, ImageLockMode.ReadWrite))
            using (var src = new LockData(source, srcRect))
            using (var map = new LockData(mapper, srcRect))
            {
                for (var x = 0; x < w; x++)
                {
                    for (var y = 0; y < h; y++)
                    {
                        if (map.IsBlackAt(x, y))
                            continue;

                        // copy the matching and all neighboring pixels to get
                        // some kind of font anti-aliasing
                        var points = from dx in Helper.Range(-1, 1)
                                        from dy in Helper.Range(-1, 1)
                                        let fy = y + dy
                                        let fx = x + dx
                                        where fy >= 0 && fy < h && fx >= 0 && fx < w
                                        select new { dx, dy };

                        foreach (var d in points)
                        {
                            var dx = x + d.dx;
                            var dy = y + d.dy;
                            dest[dx, dy] = src[dx, dy];
                        }
                    }
                }
            }

            return name;
        }