public XStrikethroughLinePoint Find(int index) { XStrikethroughLinePoint result = null; if (Points.TryGetValue(index, out result)) { return(result); } return(null); }
/// <summary> /// 横向删除线 /// </summary> /// <param name="image">需要处理的图像</param> /// <param name="span">跨度(百分比小数)</param> /// <param name="continuousDegree">连续度(像素)</param> /// <param name="backColor">背景色</param> public unsafe static void XStrikethrough(Bitmap image, float span, int continuousDegree, System.Drawing.Color backColor) { int backColorArgb = ColorHelper.ToArgb(backColor.R, backColor.G, backColor.B); int w = image.Width; int h = image.Height; BitmapData data = image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); byte *p = (byte *)data.Scan0; byte *pOri = p; int offset = data.Stride - w * 3; ImagePointToIndexHandler pointToIndexHandler = (p1, p2) => { if (p1 < 0 || p2 < 0 || p1 >= w || p2 >= h) { return(-1); } return(p1 * 3 + p2 * w * 3 + p2 * offset); }; System.Collections.Generic.Dictionary <int, XStrikethroughLine> lines = new System.Collections.Generic.Dictionary <int, XStrikethroughLine>(); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { int index = pointToIndexHandler(x, y); p = pOri + index; int a = ColorHelper.ToArgb(p[0], p[1], p[2]); if (a == backColorArgb) { continue; } XStrikethroughLine line = null; if (x > 0) { var o = LinqHelper.FirstOrDefault( LinqHelper.ThenBy( LinqHelper.OrderBy( LinqHelper.Where( LinqHelper.Select( lines.Values, p1 => new { p1, c = p1.Continuous(x, y, continuousDegree) }), p1 => p1.c != int.MinValue), p1 => p1.c), p1 => p1.p1.Y) ); if (o != null) { line = o.p1; } } XStrikethroughLinePoint point = new XStrikethroughLinePoint() { X = x, Y = y, Index = index }; if (y > 0) { int topPIndex = pointToIndexHandler(x, y - 1); byte *topP = pOri + topPIndex; point.TopPoint = new ColorScanStridePoint() { X = x, Y = y - 1, Index = topPIndex, R = topP[0], G = topP[1], B = topP[2], Color = ColorHelper.ToArgb(topP[0], topP[1], topP[2]), }; } if (y < h - 1) { int bottomPIndex = pointToIndexHandler(x, y + 1); byte *bottomP = pOri + bottomPIndex; point.BottomPoint = new ColorScanStridePoint() { X = x, Y = y + 1, Index = bottomPIndex, R = bottomP[0], G = bottomP[1], B = bottomP[2], Color = ColorHelper.ToArgb(bottomP[0], bottomP[1], bottomP[2]), }; } if (line == null) { line = new XStrikethroughLine() { X = x, Y = y, Color = a, R = p[0], G = p[1], B = p[2], Width = 1, Height = 1, Right = x + 1, Bottom = y + 1, Index = index, ImagePointToIndexHandler = pointToIndexHandler, }; line.Points.Add(index, point); lines.Add(index, line); } else { if (x > line.X) { line.Width = x - line.X + 1; line.Right = x; } if (y > line.Bottom) { line.Height = y - line.Y + 1; line.Bottom = y; } line.Points.Add(index, point); } } } System.Collections.Generic.IEnumerable <XStrikethroughLine> q = LinqHelper.Select( LinqHelper.ThenBy( LinqHelper.OrderByDescending( LinqHelper.Where( LinqHelper.Select( lines.Values, p1 => new { p1, c = ((float)p1.Width) / w }), p1 => p1.c >= span), p1 => p1.c), p1 => p1.p1.X), p1 => p1.p1); foreach (var item in q) { foreach (XStrikethroughLinePoint point in item.Points.Values) { p = pOri + point.Index; XStrikethrough_SetColor(p, pOri, point.X, point.Y, backColorArgb, pointToIndexHandler); //ColorScanStridePoint colorPoint = point.TopPoint ?? point.BottomPoint; ////p[0] = 255; ////p[1] = 0; p[2] = 0; //p[0] = colorPoint.R; //p[1] = colorPoint.G; //p[2] = colorPoint.B; ////p[0] = p[1] = p[2] = 255; } } image.UnlockBits(data); }