public static Bitmap GetToolTip(Bitmap bitmap) { var lines = ImageUtil.FindHorizontalLines(bitmap, 260, 650, new int[] { 0, 10, 0, 10, 0, 10 }); lines = lines.OrderBy(l => l.P1.X).ToList(); var groups = lines.GroupBy(l => l.P1.X).Where( l => l.Last().P1.Y - l.First().P1.Y > 200 && l.Count() > 4 && GetMaxVerticalDistance(l.ToList()) > 80 && l.Count() == l.Where(i => Math.Abs(i.XLength - l.First().XLength) < i.XLength*0.1).Count()).OrderByDescending( l => l.First().XLength).ThenByDescending(l => l.Count()); int x = groups.Count(); if (groups.Count() > 0) { lines = groups.ElementAt(0).ToList(); //Count line clusters int clusterCount = 0; int lastY = lines.ElementAt(0).P1.Y; foreach (var line in lines) { if (line.P1.Y - lastY > 5) clusterCount++; lastY = line.P1.Y; } var min = new Point(bitmap.Width, bitmap.Height); var max = new Point(0, 0); foreach (var line in groups.ElementAt(0)) { if (line.P1.X <= min.X && line.P1.Y <= min.Y) min = line.P1; else if (line.P2.X >= max.X && line.P2.Y >= max.Y) max = line.P2; } Bound bound = new Bound(min, max); if (clusterCount==2) bound = new Bound(new Point(min.X, min.Y - (int)Math.Round((42/410.0)*(max.X-min.X))), max); return bitmap.Clone(bound.ToRectangle(), bitmap.PixelFormat); } return null; }
public string ParseMeta() { Func<Color, bool> whiteFunc = c => c.B > 150 && Math.Abs(c.R - c.G) < 8 && Math.Abs(c.R - c.B) < 8; var bounds = ImageUtil.GetTextLineBounds(Resized, new Bound(new Point(80, 158 < Resized.Height ? 158 : Resized.Height), new Point(200, 218 < Resized.Height ? 218 : Resized.Height)), 13, whiteFunc, 80, 200); if (bounds.Count != 2) return ""; List<string> res = new List<string>(); foreach (var bound in bounds) { if (bound.Width < 20) continue; ImageUtil.DrawBlockBounding(Processed, bound); var newBound = new Bound(new Point(bound.P1.X - 6, bound.P1.Y - 4), new Point(bound.P2.X + 4, bound.P2.Y + 4)); var block = Resized.Clone(bound.Expand(3).ToRectangle(), Resized.PixelFormat); block = ImageUtil.ResizeImage(block, block.Width * 6, block.Height * 6); string text = Tesseract.GetTextFromBitmap(block, @"-psm 7 nobatch tesseract\d3meta"); text = text.Replace(" ", "").Replace("+", ""); if (text.StartsWith("4-") && text.EndsWith("70")) text = text.Replace("4-", "").Replace("70", "%"); res.Add(text); } return string.Join(",", res.ToArray()); }
public string ParseItemType(out string quality) { string itemType = "Unknown"; quality = "Unknown"; try { Func<Color, bool> colorFunc = c => ImageUtil.GetGrayValue(c) > 130 && !(Math.Abs(c.R - c.G) < 30 && Math.Abs(c.G - c.B) < 30); Bound itemTypebound = ImageUtil.GetBlockBounding(Resized, new Bound(new Point(s(82 / 410.0), s(55 / 410.0)), new Point(s(270 / 410.0), s(92 / 400.0))), colorFunc).Expand(6); if (itemTypebound.Height > s(46 / 400.0)) itemTypebound = new Bound(new Point(itemTypebound.P1.X, itemTypebound.P1.Y), new Point(itemTypebound.P2.X, itemTypebound.P1.Y + s(30 / 411.0))); if (itemTypebound.Width < 5) return itemType; ImageUtil.DrawBlockBounding(Processed, itemTypebound); Bitmap itemTypeBlock = Resized.Clone(itemTypebound.ToRectangle(), Resized.PixelFormat); itemTypeBlock = ImageUtil.ResizeImage(itemTypeBlock, itemTypeBlock.Width * 8, itemTypeBlock.Height * 8); //itemTypeBlock = ImageUtil.ResizeImage(itemTypeBlock, (int)(80.0 / itemTypeBlock.Height * itemTypeBlock.Width), 80); string text = Tesseract.GetTextFromBitmap(ImageUtil.Sharpen(itemTypeBlock)).Replace("\r", "").Replace("\n", " "); var words = text.Split(new[] { ' ' }); if (words.Length > 1) { string qualityString = words[0]; quality = Data.ItemQualities.OrderByDescending(i => qualityString.DiceCoefficient(i)).FirstOrDefault(); itemType = String.Join(" ", words.Skip(1)); itemType = Data.ItemTypes.OrderByDescending(i => itemType.DiceCoefficient(i)).FirstOrDefault(); return itemType; } } catch { } return itemType; }
public static List<Bound> GetTextLineBounds(Bitmap bitmap, Bound bound, int lineHeight, Func<Color, bool> colorFunc, int xScanStart, int xScanEnd) { List<Bound> res = new List<Bound>(); for (int y = bound.P1.Y; y < bound.P2.Y; y++) { bool found = false; for (int x = xScanStart; x < xScanEnd; x += 1) { Color c = bitmap.GetPixel(x, y); if (colorFunc(c)) { found = true; break; } } if (!found && res.Count > 0 && y - res[res.Count - 1].P2.Y > lineHeight * 2) break; if (!found) continue; res.Add(GetBlockBounding(bitmap, new Bound(new Point(bound.P1.X, y - 2), new Point(bound.P2.X, y + lineHeight)), colorFunc)); y += lineHeight; } return res; }
public static Bound GetBlockBounding(Bitmap bitmap, Bound bound, Func<Color, bool> func) { int xMin = 0; int yMin = 0; int xMax = 0; int yMax = 0; for (int x = bound.P1.X; x <= bound.P2.X; x++) { var range = Enumerable.Range(bound.P1.Y, bound.Height); var r = range.Where(y => func(bitmap.GetPixel(x, y))); if (r.Count() > 0) { xMin = x; break; } } for (int x = bound.P2.X; x >= bound.P1.X; x--) { var range = Enumerable.Range(bound.P1.Y, bound.Height); var r = range.Where(y => func(bitmap.GetPixel(x, y))); if (r.Count() > 0) { xMax = x; break; } } for (int y = bound.P1.Y; y <= bound.P2.Y; y++) { var range = Enumerable.Range(bound.P1.X, bound.Width); var r = range.Where(x => func(bitmap.GetPixel(x, y))); if (r.Count() > 0) { yMin = y; break; } } for (int y = bound.P2.Y; y >= bound.P1.Y; y--) { var range = Enumerable.Range(bound.P1.X, bound.Width); var r = range.Where(x => func(bitmap.GetPixel(x, y))); if (r.Count() > 0) { yMax = y; break; } } return new Bound(new Point(xMin, yMin), new Point(xMax, yMax)); }
public static Bound GetBlockBounding(Bitmap bitmap, Bound bound) { return GetBlockBounding(bitmap, bound, c => GetGrayValue(c) > 180); }
public static void DrawBlockBounding(Bitmap bitmap, Bound bound, Color color) { using (Graphics g = Graphics.FromImage(bitmap)) { g.DrawRectangle(new Pen(color), bound.ToRectangle()); } }
public static void DrawBlockBounding(Bitmap bitmap, Bound bound) { DrawBlockBounding(bitmap, bound, Color.Red); }