public override void Apply(byte **p, int length, int width, int height) { byte *ptr = *p; int bpp = length / width / height; int stride = length / height; var tmpOnes = new List <int>(); for (int i = stride + bpp; i < stride * height - stride - bpp; i += bpp) { if (ptr[i] == One) { tmpOnes.Add(i); } } int[] ones = tmpOnes.ToArray(); bool hasDeleted = true; while (hasDeleted) { hasDeleted = false; foreach (int i in ones) { if (ptr[i + 3] == Zero || ptr[i + stride] == Zero || ptr[i - 3] == Zero || ptr[i - stride] == Zero) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Two; } } foreach (int i in ones) { if (ptr[i] != Two && ( ptr[i + stride + 3] == Zero || ptr[i + stride - 3] == Zero || ptr[i - stride + 3] == Zero || ptr[i - stride - 3] == Zero)) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Three; } } foreach (int i in ones) { if (Fours.Contains(ComputeSum(i))) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Four; } } foreach (int i in ones) { if (ptr[i] == Four && Deletion.Contains(ComputeSum(i))) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Zero; } } foreach (int i in ones) { if (ptr[i] == Two && Deletion.Contains(ComputeSum(i))) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Zero; hasDeleted = true; } } foreach (int i in ones) { if (ptr[i] == Three && Deletion.Contains(ComputeSum(i))) { ptr[i] = ptr[i + 1] = ptr[i + 2] = Zero; hasDeleted = true; } } var tmp = new List <int>(ones.Length >> 1); for (int i = 0; i < ones.Length; i++) { if (ptr[ones[i]] != Zero) { tmp.Add(ones[i]); } } ones = tmp.ToArray(); } int ComputeSum(int sumOffset) { int sum = 0; if (ptr[sumOffset + bpp] != Zero) { sum += Matrix[5]; } if (ptr[sumOffset - bpp] != Zero) { sum += Matrix[3]; } sumOffset += stride; if (ptr[sumOffset + bpp] != Zero) { sum += Matrix[2]; } if (ptr[sumOffset] != Zero) { sum += Matrix[1]; } if (ptr[sumOffset - bpp] != Zero) { sum += Matrix[0]; } sumOffset -= stride + stride; if (ptr[sumOffset + bpp] != Zero) { sum += Matrix[8]; } if (ptr[sumOffset] != Zero) { sum += Matrix[7]; } if (ptr[sumOffset - bpp] != Zero) { sum += Matrix[6]; } return(sum); } }
public static unsafe Bitmap GetSkeletonization(this Bitmap sourceBitmap) { BitmapData data = sourceBitmap.LockBits( new System.Drawing.Rectangle(System.Drawing.Point.Empty, sourceBitmap.Size), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb ); byte[] p = new byte[data.Stride * data.Height]; Marshal.Copy(data.Scan0, p, 0, p.Length); sourceBitmap.UnlockBits(data); int length = data.Stride * sourceBitmap.Height; int bpp = length / sourceBitmap.Width / sourceBitmap.Height; var tmpOnes = new List <int>(); for (int i = data.Stride + bpp; i < data.Stride * sourceBitmap.Height - data.Stride - bpp; i += bpp) { if (p[i] == One) { tmpOnes.Add(i); } } int[] ones = tmpOnes.ToArray(); bool hasDeleted = true; while (hasDeleted) { hasDeleted = false; foreach (int i in ones) { if (p[i + 3] == Zero || p[i + data.Stride] == Zero || p[i - 3] == Zero || p[i - data.Stride] == Zero) { p[i] = p[i + 1] = p[i + 2] = Two; } } foreach (int i in ones) { if (p[i] != Two && ( p[i + data.Stride + 3] == Zero || p[i + data.Stride - 3] == Zero || p[i - data.Stride + 3] == Zero || p[i - data.Stride - 3] == Zero)) { p[i] = p[i + 1] = p[i + 2] = Three; } } foreach (int i in ones) { if (Fours.Contains(ComputeSum(i))) { p[i] = p[i + 1] = p[i + 2] = Four; } } foreach (int i in ones) { if (p[i] == Four && Deletion.Contains(ComputeSum(i))) { p[i] = p[i + 1] = p[i + 2] = Zero; } } foreach (int i in ones) { if (p[i] == Two && Deletion.Contains(ComputeSum(i))) { p[i] = p[i + 1] = p[i + 2] = Zero; hasDeleted = true; } } foreach (int i in ones) { if (p[i] == Three && Deletion.Contains(ComputeSum(i))) { p[i] = p[i + 1] = p[i + 2] = Zero; hasDeleted = true; } } var tmp = new List <int>(ones.Length >> 1); for (int i = 0; i < ones.Length; i++) { if (p[ones[i]] != Zero) { tmp.Add(ones[i]); } } ones = tmp.ToArray(); } int ComputeSum(int sumOffset) { int sum = 0; if (p[sumOffset + bpp] != Zero) { sum += Matrix[5]; } if (p[sumOffset - bpp] != Zero) { sum += Matrix[3]; } sumOffset += data.Stride; if (p[sumOffset + bpp] != Zero) { sum += Matrix[2]; } if (p[sumOffset] != Zero) { sum += Matrix[1]; } if (p[sumOffset - bpp] != Zero) { sum += Matrix[0]; } sumOffset -= data.Stride + data.Stride; if (p[sumOffset + bpp] != Zero) { sum += Matrix[8]; } if (p[sumOffset] != Zero) { sum += Matrix[7]; } if (p[sumOffset - bpp] != Zero) { sum += Matrix[6]; } return(sum); } Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); Marshal.Copy(p, 0, resultData.Scan0, p.Length); resultBitmap.UnlockBits(resultData); return(resultBitmap); }