public static Bitmap GetTooltip(Bitmap source, bool limitSearchArea = true) { Func<double, int> h = percent => (int)Math.Round(percent / 100.0 * source.Width); Func<double, int> v = percent => (int)Math.Round(percent / 100.0 * source.Height); Func<Color, bool> borderFunc = c => c.R < 10 && c.G < 10 && c.B < 10; // outermost tooltip 1px "black" border var cur = Cursor.Position; var projectedTooltipWidth = v(39); // 39% of screen resolution, that's pretty much how it scales Rectangle searchArea = new Rectangle(Point.Empty, source.Size); if (limitSearchArea) { // limit the area being searched by a rectangle around the mouse cursor to avoid getting incorrect tooltip (when two are visible) searchArea = Rectangle.FromLTRB( (int)Math.Max(0, cur.X - projectedTooltipWidth * 1.2), // a little more to the left than the projected tooltip width (sometimes the tooltip is not shown directly next to the cursor) 0, Math.Min(cur.X + projectedTooltipWidth * 3 / 4, source.Width), (int)(source.Height * 0.8) ); } var searchAreaSize = searchArea.Width * searchArea.Height; using (var locked = source.Lock()) { var lines = GetTooltipBlackLines(locked, searchArea, projectedTooltipWidth, v); if (lines == null || lines.Count == 0) { return null; // tooltip not found } var first = lines[0]; var last = lines.Last(); // searching for left border var range = Enumerable.Range(first.P1.X - v(1), v(0.5)).Reverse(); var left = FindVerticalBorder(locked, range, first.P1.Y, v, borderFunc); range = Enumerable.Range(first.P2.X + v(0.5), v(0.5)); var right = FindVerticalBorder(locked, range, first.P2.Y, v, borderFunc, false); if (left == null || right == null) { return null; // tooltip not found - why here? :/ } Trace.WriteLine(string.Format("Searched {0:0.00%} of pixels", locked.PixelsRead * 1f / (source.Width * source.Height))); var borderWidth = first.P1.X - left.P1.X; // distance between first pixel of first black line and the outer black 1px border found just above var ttRect = Rectangle.FromLTRB(left.P1.X, left.P1.Y, right.P1.X + 1, last.P1.Y + borderWidth); //g.DrawRectangle(Pens.Lime, ttRect); return source.Clone(ttRect, source.PixelFormat); } }
public Bitmap GetTooltip_LinesV2(Bitmap source, Rectangle searchArea, Graphics g) { Func<double, int> h = percent => (int)Math.Round(percent / 100.0 * source.Width); Func<double, int> v = percent => (int)Math.Round(percent / 100.0 * source.Height); Func<Color, bool> borderFunc = c => c.R < 10 && c.G < 10 && c.B < 10; // tooltip 1px border var searchAreaSize = searchArea.Width * searchArea.Height; var projectedTooltipWidth = v(39); // 39% of screen resolution using (var locked = source.Lock()) { var lines = GetTooltipBlackLines(locked, searchArea, projectedTooltipWidth, v, g); if (lines == null || lines.Count == 0) { return null; // tooltip not found } var first = lines[0]; var last = lines.Last(); // searching for left border var range = Enumerable.Range(first.P1.X - v(1), v(0.5)).Reverse(); var left = FindVerticalBorder(locked, range, first.P1.Y, v, borderFunc); range = Enumerable.Range(first.P2.X + v(0.5), v(0.5)); var right = FindVerticalBorder(locked, range, first.P2.Y, v, borderFunc, false); if (left == null || right == null) { return null; // tooltip not found - why here? :/ } var borderWidth = first.P1.X - left.P1.X; // distance between first pixel of first black line and the outer black 1px border found just above var ttRect = Rectangle.FromLTRB(left.P1.X, left.P1.Y, right.P1.X + 1, last.P1.Y + borderWidth); g.DrawRectangle(Pens.Lime, ttRect); Trace.WriteLine(string.Format("Searched {0:0.00%} of pixels", locked.PixelsRead * 1f / (source.Width * source.Height))); return source.Clone(ttRect, source.PixelFormat); } }
public static Rectangle GetTextBounding(Bitmap bitmap, Rectangle outerBound, Func<Color, bool> colorFunc) { using (var locked = bitmap.Lock()) { return GetTextBounding(locked, outerBound, colorFunc); } }