Example #1
0
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="imageData">image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData imageData)
        {
            // get source image size
            int width  = imageData.Width;
            int height = imageData.Height;

            // processing region's dimension
            int widthToProcess  = width;
            int heightToProcess = height;

            // if generator was specified, then generate a texture
            // otherwise use provided texture
            if (textureGenerator != null)
            {
                texture = textureGenerator.Generate(width, height);
            }
            else
            {
                widthToProcess  = Math.Min(width, texture.GetLength(1));
                heightToProcess = Math.Min(height, texture.GetLength(0));
            }

            int pixelSize = (imageData.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
            int offset    = imageData.Stride - widthToProcess * pixelSize;

            // do the job
            byte *ptr = (byte *)imageData.Scan0.ToPointer( );

            // texture
            for (int y = 0; y < heightToProcess; y++)
            {
                for (int x = 0; x < widthToProcess; x++)
                {
                    double t = texture[y, x];
                    // process each pixel
                    for (int i = 0; i < pixelSize; i++, ptr++)
                    {
                        *ptr = (byte)Math.Min(255.0f, (preserveLevel * *ptr) + (filterLevel * *ptr) * t);
                    }
                }
                ptr += offset;
            }
        }
Example #2
0
        /// <summary>
        /// Process the filter on the specified image
        /// </summary>
        ///
        /// <param name="imageData">image data</param>
        ///
        protected override unsafe void ProcessFilter(BitmapData imageData)
        {
            // source image and overlay must have same pixel format
            if (imageData.PixelFormat != overlayImage.PixelFormat)
            {
                throw new ArgumentException("Source and overlay images must have same pixel format");
            }

            // get image dimension
            int width  = imageData.Width;
            int height = imageData.Height;

            // check overlay image size
            if ((width != overlayImage.Width) || (height != overlayImage.Height))
            {
                throw new ArgumentException("Overlay image size should be equal to source image size");
            }

            // lock overlay image
            BitmapData ovrData = overlayImage.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadOnly, imageData.PixelFormat);

            // width and height to process
            int widthToProcess  = width;
            int heightToProcess = height;

            // if generator was specified, then generate a texture
            // otherwise use provided texture
            if (textureGenerator != null)
            {
                texture = textureGenerator.Generate(width, height);
            }
            else
            {
                widthToProcess  = Math.Min(width, texture.GetLength(1));
                heightToProcess = Math.Min(height, texture.GetLength(0));
            }

            int pixelSize = (imageData.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
            int offset    = imageData.Stride - widthToProcess * pixelSize;

            // do the job
            byte *ptr = (byte *)imageData.Scan0.ToPointer( );
            byte *ovr = (byte *)ovrData.Scan0.ToPointer( );

            // for each line
            for (int y = 0; y < heightToProcess; y++)
            {
                // for each pixel
                for (int x = 0; x < widthToProcess; x++)
                {
                    double t1 = texture[y, x];
                    double t2 = 1 - t1;

                    for (int i = 0; i < pixelSize; i++, ptr++, ovr++)
                    {
                        *ptr = (byte)Math.Min(255.0f, *ptr * t1 + *ovr * t2);
                    }
                }
                ptr += offset;
                ovr += offset;
            }

            overlayImage.UnlockBits(ovrData);
        }
Example #3
0
        /// <summary>
        /// Apply filter to an image
        /// </summary>
        ///
        /// <param name="imageData">Source image to apply filter to</param>
        ///
        /// <returns>Returns filter's result obtained by applying the filter to
        /// the source image</returns>
        ///
        /// <remarks>The filter accepts birmap data as input and returns the result
        /// of image processing filter as new image. The source image data are kept
        /// unchanged.</remarks>
        ///
        public Bitmap Apply(BitmapData imageData)
        {
            // get source image dimension
            int width  = imageData.Width;
            int height = imageData.Height;

            // if generator was specified, then generate a texture
            // otherwise use provided texture
            if (textureGenerator != null)
            {
                texture = textureGenerator.Generate(width, height);
            }
            else
            {
                // check existing texture
                if ((texture.GetLength(0) != height) || (texture.GetLength(1) != width))
                {
                    // sorry, but source image must have the same dimension as texture
                    throw new ArgumentException("Texture size does not match  image size");
                }
            }

            // apply first filter
            Bitmap dstImg1 = filter1.Apply(imageData);

            // check dimension of the result image
            if ((width != dstImg1.Width) || (height != dstImg1.Height))
            {
                dstImg1.Dispose( );
                // we are not handling such situations yet
                throw new ApplicationException("Filters should not change image dimension");
            }

            Bitmap dstImg2 = null;

            // apply second filter, if it was specified
            if (filter2 != null)
            {
                dstImg2 = filter2.Apply(imageData);
                // check dimension of the result image
                if ((width != dstImg2.Width) || (height != dstImg2.Height))
                {
                    dstImg1.Dispose( );
                    dstImg2.Dispose( );
                    // we are not handling such situations yet
                    throw new ApplicationException("Filters should not change image dimension");
                }
            }

            // lock second image or get source instead of it
            BitmapData dstData2 = (dstImg2 == null) ? imageData :
                                  dstImg2.LockBits(
                new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
                (dstImg2.PixelFormat == PixelFormat.Format8bppIndexed) ?
                PixelFormat.Format8bppIndexed : PixelFormat.Format24bppRgb);

            // check pixel formats
            if (dstImg1.PixelFormat != dstData2.PixelFormat)
            {
                IFilter f = new GrayscaleToRGB( );

                // convert 1st image to RGB format
                if (dstImg1.PixelFormat == PixelFormat.Format8bppIndexed)
                {
                    Bitmap t = f.Apply(dstImg1);
                    dstImg1.Dispose( );
                    dstImg1 = t;
                }

                // convert 2nd image to RGB format
                if (dstData2.PixelFormat == PixelFormat.Format8bppIndexed)
                {
                    Bitmap t = f.Apply(dstData2);

                    // dispose temporary image
                    if (dstImg2 != null)
                    {
                        dstImg2.UnlockBits(dstData2);
                        dstImg2.Dispose( );
                    }

                    dstImg2 = t;
                    // lock second image again
                    dstData2 = dstImg2.LockBits(
                        new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly,
                        PixelFormat.Format24bppRgb);
                }
            }

            // lock 1st image - result image
            BitmapData dstData1 = dstImg1.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadWrite, dstImg1.PixelFormat);

            int pixelSize = (dstData1.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
            int offset    = dstData1.Stride - width * pixelSize;

            // do the job
            unsafe
            {
                byte *dst = (byte *)dstData1.Scan0.ToPointer( );
                byte *src = (byte *)dstData2.Scan0.ToPointer( );

                if (preserveLevel != 0.0)
                {
                    // for each line
                    for (int y = 0; y < height; y++)
                    {
                        // for each pixel
                        for (int x = 0; x < width; x++)
                        {
                            double t = texture[y, x];

                            for (int i = 0; i < pixelSize; i++, src++, dst++)
                            {
                                *dst = (byte)Math.Min(255.0f, (preserveLevel * *src) + (filterLevel * *dst) * t);
                            }
                        }
                        src += offset;
                        dst += offset;
                    }
                }
                else
                {
                    // for each line
                    for (int y = 0; y < height; y++)
                    {
                        // for each pixel
                        for (int x = 0; x < width; x++)
                        {
                            double t1 = texture[y, x];
                            double t2 = 1 - t1;

                            for (int i = 0; i < pixelSize; i++, src++, dst++)
                            {
                                *dst = (byte)Math.Min(255.0f, t1 * *dst + t2 * *src);
                            }
                        }
                        src += offset;
                        dst += offset;
                    }
                }
            }

            // unlock 1st image and mask
            dstImg1.UnlockBits(dstData1);

            // dispose 2nd image
            if (dstImg2 != null)
            {
                dstImg2.UnlockBits(dstData2);
                dstImg2.Dispose( );
            }

            // return result image
            return(dstImg1);
        }