Author: lang.dennis@comcast.net Linkedin: http://www.linkedin.com/pub/1/119/293
Home Page: http://home.comcast.net/~lang.dennis


colormatrix48

C# - ColorMatrix v1.5

This C# application demonstrates the effect of using the ColorMatrix operator on an image. This program contains several sample matrix filters which you can select and modify. The top portion of the program interface contains three images. A background image, an overlay and the result of applying the color matrix on the overlay rendered on top of the background image. Each of the three panels display their image over a checkerboard background to make it easier to see partial transparent areas (alpha < 255). The bottom section of the interface shows the active color matrix filter on the left and a gallery of pre-built filters on the right.

main-screen

Program Features include:

  • Three quick image load buttons for the background and overlay image
  • Load user images into backgroud or overlay
  • Save final image
  • Edit color matrix
  • Select one or more matrix cells and use slider bar to modify selections and see results
  • Save and Load color matrix with image.
  • Select from sample filters
  • Load additional sample filters.
  • Spinning "about" dialog on open and close (eye candy)
  • Here is a code fragment which shows how you can call DrawImage with a ColorMatrix.
    
        float[][] dataArray;    // fill with filter values...
        float gamma = 1.0f;     // no change in gamma
        ImageAttributes imageAttributes = new ImageAttributes();
        imageAttributes.ClearColorMatrix();
        imageAttributes.SetColorMatrix(new ColorMatrix(dataArray), 
            ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
        imageAttributes.SetGamma(gamma, ColorAdjustType.Bitmap);
    
        Rectangle rect = new Rectangle(Point.Empty, image.Size);
        g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, imageAttributes);
    
      

    As an image is rendered using the color matrix, each pixel color channel (Red, Green, Blue, Alpha) is transformed by the color matrix. The color matrix transformation executes several math operations on the pixel color.

    
    	out(r,g,b,a) = (in(r,g,b,a)/255 * matrix_scale + matrix_offset) * 255
    
    Before appling the matrix, the input source color channels are scaled from their native range of 0..255 to a range of 0.0 to 1.0. After applying the matrix transformation, the value is scaled by 255 to return it to its natural range, clamping it between 0 and 255. The upper left 4x4 zone of the matrix is multipled against the color's 4 channels (Red, Green, Blue, Alpha). The right column of the matrix is not used. The bottom row of the matrix is used as an offset to shift the color. The color matrix can have negative numbers and numbers greater than 1. It is easier to follow the math by looking at the samples below and there are other good explanations on the web, see reference links at the bottom of this article.

    The color matrix is applied to every pixel in the image as it is drawn into the graphics buffer. The following figure shows how a single source pixel is converted to a single destination pixel. Futher down I show specific sample matrix filters.

    Source Matrix Destination
    Rs Gs Bs As
    *
    Rr Gr Br Ar 0
    Rg Gg Bg Ag 0
    Rb Gb Bb Ab 0
    Ra Ga Ba Aa 0
    Ro Go Bo Ao 0
    =
    Rd Gd Bd Ad
    Where:
    Rd = (Rr * Rs) + (Rg + Gs) + (Rb * Bs) + (Ra * As) + Ro
    Gd = (Gr * Rs) + (Gg + Gs) + (Gb * Bs) + (Ga * As) + Bo
    Bd = (Br * Rs) + (Bg + Gs) + (Bb * Bs) + (Ba * As) + Go
    Ad = (Ar * Rs) + (Ag + Gs) + (Ab * Bs) + (Aa * As) + Ao

    Modify Color Matrix

    To change the color matrix, click on the cell you want to change and enter a new value. The typical value is in the range of -1.0 to 1.0, thou any value is allowed. If you hold the control key down, you can select multiple cells and use the slider bar to adjust all of them together. The track bar will adjust the selected grid cells between the lower value in the left numeric box and the upper value in the right numeric box.

    edit-cell

    If you change cells, press the Apply button to apply the new matrix to the overlay image. If you use the slider bar, it will automatically apply the changes.

    You can save your color matrix by pressing the Save... button. The matrix is saved as an XML file with a copy of the current result image. I provide a Filter directory where sample filters are stored.


    Unit matrix which leaves the image with its original colors.

    In all of these examples, the color matrix is only applied to the 2nd image (overlay). The first image is the background, second is the overlay, and third is the result of drawing the overlay with the color matrix over the background image.

    The 4 numbers under the source column is a sample Red,Green,Blue,Alpha pixel value. The 4 numbers under the destination column is the result of applying the matrix to the sample source pixel.
    Source Matrix Destination
    10 20 30 40
    *
    1 0 0 0 0
    0 1 0 0 0
    0 0 1 0 0
    0 0 0 1 0
    0 0 0 0 0
    =
    10 20 30 40
     
    Background Overlay Bg + Overlay(colorMatrix)
    unit-bg + unit-over = unit-dest


    Example of the unit matrix which shifts colors.

    Red becomes Green, Green becomes Blue and Blue becomes Red.
    Source Matrix Destination
    10 20 30 40
    *
    0 1 0 0 0
    0 0 1 0 0
    1 0 0 0 0
    0 0 0 1 0
    0 0 0 0 0
    =
    30 10 20 40
    Background Overlay Bg + Overlay(colorMatrix)
    unit-bg + unit-over = rgb-shift-dest

    Example to exclude all colors but green and invert green magnitude.

    Source Matrix Destination
    10 20 30 40
    *
    0 0 0 0 0
    0 -1 0 0 0
    0 0 0 0 0
    0 0 0 1 0
    0 1 0 0 0
    =
    0 245 00 40
    Background Overlay Bg + Overlay(colorMatrix)
    unit-bg + unit-over = invert

    Example matrix to blend 50% of overlay image using alpha.

    When the overlay is drawn on top of the background, the alpha of the overlay controls how much of the overlay colors is stored in the destination pixel. When the alpha is less than 100% (native color value of 255) the destination pixel is calculated as followes:
    destColor = overlayColor * alphaPercent + backgroundColr * (100% - alphaPercent)

    Example with Alpha=60%:
    Overlay Background Equation Result
    Red 10 20 10*0.6 + 20*0.4 14
    Green 20 20 20*0.6 + 20*0.4 20
    Blue 30 20 30*0.6 + 20*0.4 26
    An overlay color(10,20,30) blended at 60% on top of a gray color(20,20,20) becomes (14,20,26)

    Source Matrix Destination
    10 20 30 40
    *
    1 0 0 0 0
    0 1 0 0 0
    0 0 1 0 0
    0 0 0 0.5 0
    0 0 0 0 0
    =
    10 20 30 20
    Background Overlay Bg + Overlay(colorMatrix)
    unit-bg + unit-over = alpha50

    Grey scale

    By setting the upper 3x3 section of the color matrix to the same value, it produces a grey scale image. All three color channels (red, green, blue) are set to the sum of the source channels (Rs+Gs+Bs). To reduce saturation (color exceeding maximum range), I included a -0.5 in the offset row. By using a negative offset I reduce the intensity.
    (Red * 1 + Blue * 1 + Green * 1) -0.5 * 256 = destination_color_channel
    100 + 20 + 30 - 128 = 22
    Source Matrix Destination
    100 20 30 40
    *
    1 1 1 0 0
    1 1 1 0 0
    1 1 1 0 0
    0 0 0 1 0
    -0.5-0.5-0.5 0 0
    =
    22 22 22 40
    Background Overlay Bg + Overlay(colorMatrix)
    unit-bg + unit-over = grey

    Top


    Author: lang.dennis@comcast.net Linkedin: http://www.linkedin.com/pub/1/119/293
    Home Page: http://home.comcast.net/~lang.dennis