Example #1
0
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="sourceData">Source image data</param>
        /// <param name="destinationData">Destination image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData sourceData, BitmapData destinationData)
        {
            byte *src = null;
            byte *dst = (byte *)destinationData.Scan0.ToPointer( );

            // get width and height
            int    width = sourceData.Width;
            int    height = sourceData.Height;
            int    widthM1 = width - 1;
            int    heightM1 = height - 1;
            int    stride = destinationData.Stride;
            int    offset = stride - width;
            double ex, ey, weight, weightTotal = 0, total = 0;

            // convert image to grayscale if it is color
            Bitmap     grayImage = null;
            BitmapData grayData  = null;

            if (sourceData.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                // create grayscale filter
                IFilter filter = new GrayscaleRMY( );
                // do the processing
                grayImage = filter.Apply(sourceData);
                // lock the image
                grayData = grayImage.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                // set source pointer
                src = (byte *)grayData.Scan0.ToPointer( );
            }
            else
            {
                src = (byte *)sourceData.Scan0.ToPointer( );
            }

            // --- 1st pass - collecting statistics

            // skip the first line for the first pass
            src += stride;

            // for each line
            for (int y = 1; y < heightM1; y++)
            {
                src++;
                // for each pixels
                for (int x = 1; x < widthM1; x++, src++)
                {
                    // the equations are:
                    // ex = I(x + 1, y) - I(x - 1, y)
                    // ey = I(x, y + 1) - I(x, y - 1)
                    // weight = max(ex, ey)
                    // weightTotal += weight
                    // total += weight * I(x, y)

                    ex           = src[1] - src[-1];
                    ey           = src[stride] - src[-stride];
                    weight       = (ex > ey) ? ex : ey;
                    weightTotal += weight;
                    total       += weight * (*src);
                }
                src += offset + 1;
            }

            // calculate threshold
            threshold = (weightTotal == 0) ? (byte)0 : (byte)(total / weightTotal);

            // --- 2nd pass - thresholding
            src = (grayData != null) ? (byte *)grayData.Scan0.ToPointer( ) : (byte *)sourceData.Scan0.ToPointer( );

            // for each line
            for (int y = 0; y < height; y++)
            {
                // for all pixels
                for (int x = 0; x < width; x++, src++, dst++)
                {
                    *dst = (byte)((*src <= threshold) ? 0 : 255);
                }
                src += offset;
                dst += offset;
            }

            // release gray image, if there was conversion
            if (grayData != null)
            {
                grayImage.UnlockBits(grayData);
                grayImage.Dispose( );
            }
        }
Example #2
0
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="sourceData">Source image data</param>
        /// <param name="destinationData">Destination image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData sourceData, BitmapData destinationData)
        {
            byte *src = null;
            byte *dst = (byte *)destinationData.Scan0.ToPointer( );

            // get width and height
            int width    = sourceData.Width;
            int height   = sourceData.Height;
            int widthM1  = width - 1;
            int heightM1 = height - 1;
            int stride   = destinationData.Stride;
            int offset   = stride - width;

            int d, max, v;

            // convert image to grayscale if it is color
            Bitmap     grayImage = null;
            BitmapData grayData  = null;

            if (sourceData.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                // create grayscale filter
                IFilter filter = new GrayscaleRMY( );
                // do the processing
                grayImage = filter.Apply(sourceData);
                // lock the image
                grayData = grayImage.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                // set source pointer
                src = (byte *)grayData.Scan0.ToPointer( );
            }
            else
            {
                src = (byte *)sourceData.Scan0.ToPointer( );
            }

            // do the processing job

            // skip one stride
            src += stride;
            dst += stride;

            // for each line
            for (int y = 1; y < heightM1; y++)
            {
                src++;
                dst++;

                // for each pixel
                for (int x = 1; x < widthM1; x++, src++, dst++)
                {
                    max = 0;
                    v   = *src;

                    // top-left
                    d = v - src[-stride - 1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // top
                    d = v - src[-stride];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // top-right
                    d = v - src[-stride + 1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // left
                    d = v - src[-1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // right
                    d = v - src[1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // bottom-left
                    d = v - src[stride - 1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // bottom
                    d = v - src[stride];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }
                    // bottom-right
                    d = v - src[stride + 1];
                    if (d < 0)
                    {
                        d = -d;
                    }
                    if (d > max)
                    {
                        max = d;
                    }

                    *dst = (byte)max;
                }
                src += offset + 1;
                dst += offset + 1;
            }

            // release gray image, if there was conversion
            if (grayData != null)
            {
                grayImage.UnlockBits(grayData);
                grayImage.Dispose( );
            }
        }
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="sourceData">Source image data</param>
        /// <param name="destinationData">Destination image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData sourceData, BitmapData destinationData)
        {
            // get image dimension
            width    = sourceData.Width;
            height   = sourceData.Height;
            stride   = destinationData.Stride;
            widthM1  = width - 1;
            heightM1 = height - 1;

            // allocate memory for source copy
            IntPtr sourceCopy = Win32.LocalAlloc(Win32.MemoryFlags.Fixed, destinationData.Stride * height);

            // check source image format
            if (sourceData.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                // copy source image
                Win32.memcpy(sourceCopy, sourceData.Scan0, destinationData.Stride * height);
            }
            else
            {
                // convert color image to grayscale
                IFilter filter    = new GrayscaleRMY( );
                Bitmap  grayImage = filter.Apply(sourceData);
                // copy the image
                BitmapData grayData = grayImage.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);

                Win32.memcpy(sourceCopy, grayData.Scan0, destinationData.Stride * height);

                grayImage.UnlockBits(grayData);
                // free the gray image
                grayImage.Dispose( );
            }

            int offset = stride - width;
            int v, error;

            // do the job
            byte *src = (byte *)sourceCopy.ToPointer( );
            byte *dst = (byte *)destinationData.Scan0.ToPointer( );

            // for each line
            for (y = 0; y < height; y++)
            {
                // for each pixels
                for (x = 0; x < width; x++, src++, dst++)
                {
                    v = *src;

                    // fill the next destination pixel
                    if (v < 128)
                    {
                        *dst = 0;
                        error = v;
                    }
                    else
                    {
                        *dst = 255;
                        error = v - 255;
                    }

                    // do error diffusion
                    Diffuse(error, src);
                }
                src += offset;
                dst += offset;
            }

            // free memory for image copy
            Win32.LocalFree(sourceCopy);
        }
Example #4
0
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="sourceData">Source image data</param>
        /// <param name="destinationData">Destination image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData sourceData, BitmapData destinationData)
        {
            byte *src = null;
            byte *dst = (byte *)destinationData.Scan0.ToPointer( );

            // get width and height
            int width    = sourceData.Width;
            int height   = sourceData.Height;
            int widthM1  = width - 1;
            int heightM1 = height - 1;
            int stride   = destinationData.Stride;
            int offset   = stride - width;

            // loop and array indexes
            int i, j, ir;
            // variables for gradient calculation
            double v, gx, gy, g, max = 0;

            // convert image to grayscale if it is color
            Bitmap     grayImage = null;
            BitmapData grayData  = null;

            if (sourceData.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                // create grayscale filter
                IFilter filter = new GrayscaleRMY( );
                // do the processing
                grayImage = filter.Apply(sourceData);
                // lock the image
                grayData = grayImage.LockBits(
                    new Rectangle(0, 0, width, height),
                    ImageLockMode.ReadOnly, PixelFormat.Format8bppIndexed);
                // set source pointer
                src = (byte *)grayData.Scan0.ToPointer( );
            }
            else
            {
                src = (byte *)sourceData.Scan0.ToPointer( );
            }

            // do the processing job
            // skip one stride
            src += stride;
            dst += stride;

            // for each line
            for (int y = 1; y < heightM1; y++)
            {
                src++;
                dst++;

                // for each pixel
                for (int x = 1; x < widthM1; x++, src++, dst++)
                {
                    gx = gy = 0;
                    // for each kernel row
                    for (i = 0; i < 3; i++)
                    {
                        ir = i - 1;
                        // for each kernel column
                        for (j = 0; j < 3; j++)
                        {
                            // source value
                            v = src[ir * stride + j - 1];

                            gx += v * xKernel[i, j];
                            gy += v * yKernel[i, j];
                        }
                    }
                    // get gradient value
//					g = Math.Min( Math.Sqrt( gx * gx + gy * gy ), 255 );
                    g = Math.Min(Math.Abs(gx) + Math.Abs(gy), 255);                             // approximation
                    if (g > max)
                    {
                        max = g;
                    }
                    *dst = (byte)g;
                }
                src += (offset + 1);
                dst += (offset + 1);
            }

            // do we need scaling
            if ((scaleIntensity) && (max != 255))
            {
                // make the second pass for intensity scaling
                double factor = 255.0 / (double)max;
                dst = (byte *)destinationData.Scan0.ToPointer( ) + stride;

                // for each line
                for (int y = 1; y < heightM1; y++)
                {
                    dst++;
                    // for each pixel
                    for (int x = 1; x < widthM1; x++, dst++)
                    {
                        *dst = (byte)(factor * *dst);
                    }
                    dst += (offset + 1);
                }
            }

            // release gray image, if there was conversion
            if (grayData != null)
            {
                grayImage.UnlockBits(grayData);
                grayImage.Dispose( );
            }
        }