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)); }
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)); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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; }
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); }
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; }