2 out of 2 rated this helpful - Rate this topic

ColorMatrix Class

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. This class cannot be inherited.

System.Object
  System.Drawing.Imaging.ColorMatrix

Namespace:  System.Drawing.Imaging
Assembly:  System.Drawing (in System.Drawing.dll)
public sealed class ColorMatrix

The ColorMatrix type exposes the following members.

  Name Description
Public method ColorMatrix() Initializes a new instance of the ColorMatrix class.
Public method ColorMatrix(Single[][]) Initializes a new instance of the ColorMatrix class using the elements in the specified matrix newColorMatrix.
Top
  Name Description
Public property Item Gets or sets the element at the specified row and column in the ColorMatrix.
Public property Matrix00 Gets or sets the element at the 0 (zero) row and 0 column of this ColorMatrix.
Public property Matrix01 Gets or sets the element at the 0 (zero) row and first column of this ColorMatrix.
Public property Matrix02 Gets or sets the element at the 0 (zero) row and second column of this ColorMatrix.
Public property Matrix03 Gets or sets the element at the 0 (zero) row and third column of this ColorMatrix. Represents the alpha component.
Public property Matrix04 Gets or sets the element at the 0 (zero) row and fourth column of this ColorMatrix.
Public property Matrix10 Gets or sets the element at the first row and 0 (zero) column of this ColorMatrix.
Public property Matrix11 Gets or sets the element at the first row and first column of this ColorMatrix.
Public property Matrix12 Gets or sets the element at the first row and second column of this ColorMatrix.
Public property Matrix13 Gets or sets the element at the first row and third column of this ColorMatrix. Represents the alpha component.
Public property Matrix14 Gets or sets the element at the first row and fourth column of this ColorMatrix.
Public property Matrix20 Gets or sets the element at the second row and 0 (zero) column of this ColorMatrix.
Public property Matrix21 Gets or sets the element at the second row and first column of this ColorMatrix.
Public property Matrix22 Gets or sets the element at the second row and second column of this ColorMatrix.
Public property Matrix23 Gets or sets the element at the second row and third column of this ColorMatrix.
Public property Matrix24 Gets or sets the element at the second row and fourth column of this ColorMatrix.
Public property Matrix30 Gets or sets the element at the third row and 0 (zero) column of this ColorMatrix.
Public property Matrix31 Gets or sets the element at the third row and first column of this ColorMatrix.
Public property Matrix32 Gets or sets the element at the third row and second column of this ColorMatrix.
Public property Matrix33 Gets or sets the element at the third row and third column of this ColorMatrix. Represents the alpha component.
Public property Matrix34 Gets or sets the element at the third row and fourth column of this ColorMatrix.
Public property Matrix40 Gets or sets the element at the fourth row and 0 (zero) column of this ColorMatrix.
Public property Matrix41 Gets or sets the element at the fourth row and first column of this ColorMatrix.
Public property Matrix42 Gets or sets the element at the fourth row and second column of this ColorMatrix.
Public property Matrix43 Gets or sets the element at the fourth row and third column of this ColorMatrix. Represents the alpha component.
Public property Matrix44 Gets or sets the element at the fourth row and fourth column of this ColorMatrix.
Top
  Name Description
Public method Equals(Object) Determines whether the specified Object is equal to the current Object. (Inherited from Object.)
Protected method Finalize Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.)
Public method GetHashCode Serves as a hash function for a particular type. (Inherited from Object.)
Public method GetType Gets the Type of the current instance. (Inherited from Object.)
Protected method MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Public method ToString Returns a string that represents the current object. (Inherited from Object.)
Top

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.

For example, suppose you want to start with the color (0.2, 0.0, 0.4, 1.0) and apply the following transformations:

  1. Double the red component

  2. Add 0.2 to the red, green, and blue components

The following matrix multiplication will perform the pair of transformations in the order listed.

Recoloring

The elements of a color matrix are indexed (zero-based) by row and then column. For example, the entry in the fifth row and third column of matrix M is denoted by M[4][2].

The 5×5 identity matrix (shown in the following illustration) has 1s on the diagonal and 0s everywhere else. If you multiply a color vector by the identity matrix, the color vector does not change. A convenient way to form the matrix of a color transformation is to start with the identity matrix and make a small change that produces the desired transformation.

Recoloring

For a more detailed discussion of matrices and transformations, see Coordinate Systems and Transformations.

The following example takes an image that is all one color (0.2, 0.0, 0.4, 1.0) and applies the transformation described in the preceding paragraphs.

The following illustration shows the original image on the left and the transformed image on the right.

Colors

The code in the following example uses the following steps to perform the recoloring:

  1. Initialize a ColorMatrix object.

  2. Create an ImageAttributes object and pass the ColorMatrix object to the SetColorMatrix method of the ImageAttributes object.

  3. Pass the ImageAttributes object to the DrawImage method of a Graphics object.

The preceding example is designed for use with Windows Forms, and it requires PaintEventArgs e, which is a parameter of the Paint event handler


Image image = new Bitmap("InputColor.bmp");
ImageAttributes imageAttributes = new ImageAttributes();
int width = image.Width;
int height = image.Height;

float[][] colorMatrixElements = { 
   new float[] {2,  0,  0,  0, 0},        // red scaling factor of 2
   new float[] {0,  1,  0,  0, 0},        // green scaling factor of 1
   new float[] {0,  0,  1,  0, 0},        // blue scaling factor of 1
   new float[] {0,  0,  0,  1, 0},        // alpha scaling factor of 1
   new float[] {.2f, .2f, .2f, 0, 1}};    // three translations of 0.2

ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

imageAttributes.SetColorMatrix(
   colorMatrix,
   ColorMatrixFlag.Default,
   ColorAdjustType.Bitmap);

e.Graphics.DrawImage(image, 10, 10);

e.Graphics.DrawImage(
   image,
   new Rectangle(120, 10, width, height),  // destination rectangle 
   0, 0,        // upper-left corner of source rectangle 
   width,       // width of source rectangle
   height,      // height of source rectangle
   GraphicsUnit.Pixel,
   imageAttributes);


.NET Framework

Supported in: 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework Client Profile

Supported in: 4, 3.5 SP1

Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2

The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Did you find this helpful?
(1500 characters remaining)
Community Content Add
Annotations FAQ
RGB bug when alpha adjusted for Format8bppIndexed Bitmap
The RGB color of a Bitmap with a format of Format8bppIndexed will appear wrong (e.g., inverted color) when a ColorMatrix is used to adjust the scale of the alpha channel when drawing that Bitmap. 

This will occur for PNG files with 8-bit indexed color.  Many PNG files are 24-bit RGB or 32-bit RGBA, and thus avoid the problem.

This will occur for some GIF files.  GIF files are always indexed color, but some GIF files nonetheless load in to Bitmap objects as Format32bppArgb, and thus avoid the problem.

The following is not quite a complete program, but the code contains all relevant factors:

    float[][] SemiTransparentColorMatrixElements = 
    {
        new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f, 0.0f, 0.6f, 0.0f },  // NOTICE THE 0.6 TO MAKE THE ALPHA NON-OPAQUE
        new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f }
    };

    System.Drawing.Imaging.ColorMatrix SemiTransparentColorMatrix =
        new System.Drawing.Imaging.ColorMatrix(SemiTransparentColorMatrixElements);

    System.Drawing.Imaging.ImageAttributes SemiTransparentImageAttributes =
        new System.Drawing.Imaging.ImageAttributes();

    SemiTransparentImageAttributes.SetColorMatrix
    (
        SemiTransparentColorMatrix,
        System.Drawing.Imaging.ColorMatrixFlag.Default,
        System.Drawing.Imaging.ColorAdjustType.Bitmap
    );

   
    System.Drawing.Bitmap bitmap =
        new System.Drawing.Bitmap( filePathAndName );


    // The following will appear to invert the RGB colors
    // if the bitmap loaded directly from the file retains
    // a format of Format8bppIndexed, but will appear OK
    // for Format24bppRgb and Format32bppArgb.

    g.DrawImage
    (
        (System.Drawing.Image) bitmap,
        destinationRectangle,
        sourceRectangle.Left,
        sourceRectangle.Top,
        sourceRectangle.Width,
        sourceRectangle.Height,
        System.Drawing.GraphicsUnit.Pixel,
        SemiTransparentImageAttributes
    );


I was surprised by the odd behavior for bitmaps created from files with 8-bit indexed color, but I can imagine how coping with bitmaps with indexed-color internal formats might be subject to various speed penalties and drawing glitches like this.

My work-around is to check the Bitmap object after loading an image from a file.  If the Bitmap format is neither Format24bppRgb nor Format32bppArgb, then I create a new Bitmap instance of Format32bppArgb format and copy the first bitmap to the new bitmap, in a manner that preserves promotes colors to 32-bit RGBA reliably.