Javascript required
Skip to content Skip to sidebar Skip to footer

Winfroms Draw Image With Point Filtring

Article purpose

This article is based around creating basic Image filters. The different types of filters discussed are: Grayscale, Transparency, Image Negative and Sepia tone. All filters are implemented as extension methods targeting the Image class, as well as the Bitmap class as the result of inheritance and upcasting.

Note: This article is a follow up to C# How to: Image filtering by directly manipulating Pixel ARGB values. The previously published related article implements image filtering by performing calculations and updating image pixel colour component values namely Alpha , Red , Green and Blue . This article achieves the same image filtering through implementing various ColorMatrix transformations, in essence providing an alternative solution. For the sake of convenience I have included the pixel manipulation extension methods in addition to the ColorMatrix extension methods detailed by this article.

Sample source code

This article is accompanied by a sample source code Visual Studio project which is available for download here.

ColorMatrix Image Filters

Implementing a ColorMatrix

From MSDN Documentation:

Defines a 5 x 5 matrix that contains the coordinates for the RGBAW space. Several methods of the ImageAttributes class adjust image colors by using a color matrix.

The matrix coefficients constitute a 5 x 5 linear transformation that is used for transforming ARGB homogeneous values. For example, an ARGB vector is represented as red, green, blue, alpha and w, where w is always 1.

When implementing a translation using the ColorMatrix class values specified are added to one or more of the four colour components. A value that is to be added may only range from 0 to 1 inclusive. Note that adding a negative value results in subtracting values. A good article that illustrates implementing a ColorMatrix can be found on MSDN: How to: Translate Image Colors.

The following code snippet provides the implementation of the ApplyColorMatrix method.

            private            static            Bitmap            ApplyColorMatrix(Image            sourceImage,            ColorMatrix            colorMatrix) {            Bitmap            bmp32BppSource = GetArgbCopy(sourceImage);            Bitmap            bmp32BppDest =            new            Bitmap(bmp32BppSource.Width, bmp32BppSource.Height,            PixelFormat.Format32bppArgb);            
using (Graphics graphics = Graphics.FromImage(bmp32BppDest)) { ImageAttributes bmpAttributes = new ImageAttributes(); bmpAttributes.SetColorMatrix(colorMatrix); graphics.DrawImage(bmp32BppSource, new Rectangle(0, 0, bmp32BppSource.Width, bmp32BppSource.Height), 0, 0, bmp32BppSource.Width, bmp32BppSource.Height, GraphicsUnit.Pixel, bmpAttributes);
}
bmp32BppSource.Dispose();
return bmp32BppDest; }

The ApplyColorMatrix method signature defines a parameter of type Image and a second parameter of type ColorMatrix. This method is intended to apply the specified ColorMatrix upon the Image parameter specified.

The source image is firstly copied in order to ensure that the image that is to be transformed is defined with a pixel format of 32 bits per pixel , consisting of the colour components Alpha , Red , Green and Blue – PixelFormat.Format32bppArgb. Next we create a blank memory bitmap defined to reflect the same size dimensions as the original source image. A ColorMatrix can be implemented by means of applying an ImageAttribute when invoking the DrawImage defined by the Graphics class.

Creating an ARGB copy

The source code snippet listed below converts source images into 32Bit ARGB formatted images:

            private            static            Bitmap            GetArgbCopy(Image            sourceImage) {            Bitmap            bmpNew =            new            Bitmap(sourceImage.Width, sourceImage.Height,            PixelFormat.Format32bppArgb);            
using(Graphics graphics = Graphics.FromImage(bmpNew)) { graphics.DrawImage(sourceImage, new Rectangle (0, 0, bmpNew.Width, bmpNew.Height), new Rectangle (0, 0, bmpNew.Width, bmpNew.Height), GraphicsUnit.Pixel); graphics.Flush(); }
return bmpNew; }

The GetArgbCopy method creates a blank memory Bitmap having the same size dimensions as the source image. The newly created Bitmap is explicitly specified to conform to a 32Bit ARGB format. By making use of a Graphics object of which the context is bound to the new Bitmap instance the source code draws the original image to the new Bitmap.

The Transparency Filter

The transparency filter is intended to create a copy of an image, increase the copy's level of transparency and return the modified copy to the calling code. Listed below is source code which defines the DrawWithTransparency extension method.

            public            static            Bitmap            DrawWithTransparency(this            Image            sourceImage) {            ColorMatrix            colorMatrix =            new            ColorMatrix(new            float[][]                         {            new            float[]{1, 0, 0, 0, 0},            new            float[]{0, 1, 0, 0, 0},            new            float[]{0, 0, 1, 0, 0},            new            float[]{0, 0, 0, 0.3f, 0},            new            float[]{0, 0, 0, 0, 1}                         });            
return ApplyColorMatrix(sourceImage, colorMatrix); }

Due to the ApplyColorMatrix method defined earlier implementing an image filter simply consists of defining the filter algorithm in the form of a ColorMatrix and then invoking ApplyColorMatrix.

The ColorMatrix is defined to apply no change to the Red , Green and Blue components whilst reducing the Alpha component by 70%.

Image Filters Transparency ColorMatrix

The Grayscale Filter

All of the image filter extension methods illustrated in this article are implemented in a fashion similar to the DrawWithTransparency method. The DrawAsGrayscale extension method is implemented as follows:

            public            static            Bitmap            DrawAsGrayscale(this            Image            sourceImage) {            ColorMatrix            colorMatrix =            new            ColorMatrix(new            float[][]                         {            new            float[]{.3f, .3f, .3f, 0, 0},            new            float[]{.59f, .59f, .59f, 0, 0},            new            float[]{.11f, .11f, .11f, 0, 0},            new            float[]{0, 0, 0, 1, 0},            new            float[]{0, 0, 0, 0, 1}                         });            
return ApplyColorMatrix(sourceImage, colorMatrix); }

The grayscale filter is achieved by adding together 11% blue , 59% green and 30% red , then assigning the total value to each colour component.

Image Filters Grayscale ColorMatrix

The Sepia Tone Filter

The sepia tone filter is implemented in the extension method DrawAsSepiaTone . Notice how this method follows the same convention as the previously discussed filters. The source code listing is detailed below.

            public            static            Bitmap            DrawAsSepiaTone(this            Image            sourceImage) {            ColorMatrix            colorMatrix =            new            ColorMatrix(new            float[][]                  {            new            float[]{.393f, .349f, .272f, 0, 0},            new            float[]{.769f, .686f, .534f, 0, 0},            new            float[]{.189f, .168f, .131f, 0, 0},            new            float[]{0, 0, 0, 1, 0},            new            float[]{0, 0, 0, 0, 1}                 });            
return ApplyColorMatrix(sourceImage, colorMatrix); }

The formula used to calculate a sepia tone differs significantly from the grayscale filter discussed previously. The formula can be simplified as follows:

  • Red Component: Sum total of: 39.3% red, 34.9% green , 27.2% blue
  • Green Component: Sum total of: 76.9% red, 68.6% green , 53.4% blue
  • Blue Component: Sum total of: 18.9% red, 16.8% green , 13.1% blue

Image Filters Sepia ColorMatrix

The Negative Image Filter

We can implement an image filter that resembles film negatives by literally inverting every pixel's colour components. Listed below is the source code implementation of the DrawAsNegative extension method.

            public            static            Bitmap            DrawAsNegative(this            Image            sourceImage) {            ColorMatrix            colorMatrix =            new            ColorMatrix(new            float[][]                      {            new            float[]{-1, 0, 0, 0, 0},            new            float[]{0, -1, 0, 0, 0},            new            float[]{0, 0, -1, 0, 0},            new            float[]{0, 0, 0, 1, 0},            new            float[]{1, 1, 1, 1, 1}                     });            
return ApplyColorMatrix(sourceImage, colorMatrix); }

Notice how the negative image filter subtracts 1 from each colour component, remember the valid range being 0 to 1 inclusive. This ColorMatrix in reality inverts each pixel's colour component bits. The transform being applied can also be expressed as implementing the bitwise compliment operator on each pixel.

Image Filters Negative Color Matrix

The implementation

The image filters described in this article are all implemented by means of a Windows Forms application. Image filtering is applied by selecting the corresponding radio button. The source image loaded from the file system serves as input to the various image filter methods, the filtered image copy returned will be displayed next to the original source image.

The following code snippet details the radio button checked changed event handler :

            private            void            OnCheckChangedEventHandler(object            sender,            EventArgs            e) {            if            (picSource.BackgroundImage !=            null)     {            if            (rdGrayscaleBits.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.CopyAsGrayscale();         }            else            if            (rdGrayscaleDraw.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.DrawAsGrayscale();         }            else            if            (rdTransparencyBits.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.CopyWithTransparency();         }            else            if            (rdTransparencyDraw.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.DrawWithTransparency();         }            else            if            (rdNegativeBits.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.CopyAsNegative();         }            else            if            (rdNegativeDraw.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.DrawAsNegative();         }            else            if            (rdSepiaBits.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.CopyAsSepiaTone();         }            else            if            (rdSepiaDraw.Checked ==            true)         {              picOutput.BackgroundImage = picSource.BackgroundImage.DrawAsSepiaTone();         }     } }

Related Articles

  • C# How to: Image filtering by directly manipulating Pixel ARGB values
  • C# How to: Image filtering implemented using a ColorMatrix
  • C# How to: Blending Bitmap images using colour filters
  • C# How to: Bitmap Colour Substitution implementing thresholds
  • C# How to: Generating Icons from Images
  • C# How to: Swapping Bitmap ARGB Colour Channels
  • C# How to: Bitmap Pixel manipulation using LINQ Queries
  • C# How to: Linq to Bitmaps – Partial Colour Inversion
  • C# How to: Bitmap Colour Balance
  • C# How to: Bi-tonal Bitmaps
  • C# How to: Bitmap Colour Tint
  • C# How to: Bitmap Colour Shading
  • C# How to: Image Solarise
  • C# How to: Image Contrast
  • C# How to: Bitwise Bitmap Blending
  • C# How to: Image Arithmetic

Winfroms Draw Image With Point Filtring

Source: https://softwarebydefault.com/2013/03/03/colomatrix-image-filters/