示例#1
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 mask dimension
            int width  = mask.Width;
            int height = mask.Height;

            // check source image size
            if ((width != imageData.Width) || (height != imageData.Height))
            {
                // sorry, but source image must have the same dimension as mask image
                throw new ArgumentException("Source image has wrong dimension (does not equal to mask dimension");
            }

            // 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);

            // lock mask bitmap data
            BitmapData maskData = mask.LockBits(
                new Rectangle(0, 0, width, height),
                ImageLockMode.ReadOnly, mask.PixelFormat);

            int pixelSize  = (dstImg1.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
            int offset     = dstData1.Stride - width * pixelSize;
            int maskInc    = (mask.PixelFormat == PixelFormat.Format8bppIndexed) ? 1 : 3;
            int maskOffset = maskData.Stride - width * maskInc;

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

                // for each line
                for (int y = 0; y < height; y++)
                {
                    // for each pixel
                    for (int x = 0; x < width; x++, m += maskInc)
                    {
                        if (*m != 0)
                        {
                            for (int i = 0; i < pixelSize; i++, src++, dst++)
                            {
                                *dst = *src;
                            }
                        }
                        else
                        {
                            src += pixelSize;
                            dst += pixelSize;
                        }
                    }
                    src += offset;
                    dst += offset;
                    m   += maskOffset;
                }
            }

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

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

            // return result image
            return(dstImg1);
        }
示例#2
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);
        }