예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }