Using ColorMatrix for Creating Negative Image

.NET provides two classes for image transformations: Matrix, used for geometric transformations, and ColorMatrix, used for color transformations.

One of such color transformations is inverting or negating. This means subtracting each color component from 255. Black (0,0,0) becomes White (255, 255, 255), and Green (0, 255, 0) becomes Magenta (255, 0, 255).

You can find many examples on the web that look like this:

public Bitmap Transform(Bitmap source)
    //create a blank bitmap the same size as original
    Bitmap newBitmap = new Bitmap(source.Width, source.Height);

    //get a graphics object from the new image
    Graphics g = Graphics.FromImage(newBitmap);

    // create the negative color matrix
    ColorMatrix colorMatrix = new ColorMatrix();
    colorMatrix.Matrix00 = colorMatrix.Matrix11 = colorMatrix.Matrix22 = -1f;
    colorMatrix.Matrix33 = colorMatrix.Matrix44 = 1f;

    // create some image attributes
    ImageAttributes attributes = new ImageAttributes();


    g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
                0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);

    //dispose the Graphics object

    return newBitmap;

Using this code one can get a negative image.

Original image
Original image

Negative image
Negative image

This runs fine on Windows XP. But when I ran it on Windows 7, I was getting only a black image. All the pixels were ARGB(255, 0, 0, 0). This was how it looked:

Incorrectly transformed image
Incorrectly transformed image

I was surprised to learn that it worked on Windows XP, but not on Windows 7. I don’t have Windows Vista to test but I guess it’s the same as with Windows 7. I thought it must be something in the GDI+ library, because building with .NET 3.5 SP1 or 4.0 Beta 2 didn’t change a thing.

After trying different things, I figured out what the problem was: the color matrix was incorrect. It must be defined like this:

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, 0, 1}

With this change the Transform function produces a correct negative image, regardless the operating system or the .NET framework version.

However, what I don’t know yet, is why it worked on Windows XP. The only conclusion I can draw is that the GDI+ implementation has a fault there, that was later corrected. That’s why an incorrect color matrix produced a correct transformation on Windows XP.

4 Replies to “Using ColorMatrix for Creating Negative Image”

  1. you rock….this was driving me nuts as well. i had a program that worked for years on XP and messed up on windows 7. I don’t know how you figured it out, but I’m glad you did.

  2. Thanks, was looking at a black image for an hour now, not figuring out what the problem was, until I found this.

    Thanks for sharing.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.