Use an ImageAttributes object to adjust an image’s brightness in C#

adjust an image's brightness

This example demonstrates a fast way to adjust an image’s brightness. The idea is simple: move each pixel’s red, green, and blue color components closer to the minimum or maximum values 0 and 255. For example, if a pixel’s components are 128, 32, 254 and you change them to 64, 16, 127, you make the pixel darker.

You can loop through an image’s pixels and adjust them one-by-one, but there’s a much faster method: draw the image into a new Bitmap using an ImageAttributes object to adjust the pixels’ values.

When transforming colors in this way, colors are represented using a vector with 5 entries. The first four are for the pixel’s red, green, blue, and alpha (opacity) components. The fifth entry is a scaling value with value 1.

A ColorMatrix object can transform an image’s colors by multiplying each pixel’s color vector by a 5-by-5 matrix of floating point values.

The identity matrix, with 1’s down the diagonal and 0s everywhere else, leaves all colors unchanged.

The following matrix applies the scaling factor S to the pixel’s red, green, and blue components.

S 0 0 0 0
0 S 0 0 0
0 0 S 0 0
0 0 0 1 0
0 0 0 0 1

If you multiply this matrix by the generic pixel color vector [r, g, b, a, 1], the result is [S * r, S * g, S * b, a, 1], so this matrix scales the color components as desired.

The AdjustBrightness method shown in the following code uses an ImageAttributes object to apply this kind of scaling ColorMatrix to the pixels in an image.

// Adjust the image's brightness.
private Bitmap AdjustBrightness(Image image, float brightness)
{
    // Make the ColorMatrix.
    float b = brightness;
    ColorMatrix cm = new ColorMatrix(new float[][]
        {
            new float[] {b, 0, 0, 0, 0},
            new float[] {0, b, 0, 0, 0},
            new float[] {0, 0, b, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, 0, 1},
        });
    ImageAttributes attributes = new ImageAttributes();
    attributes.SetColorMatrix(cm);

    // Draw the image onto the new bitmap while applying
    // the new ColorMatrix.
    Point[] points =
    {
        new Point(0, 0),
        new Point(image.Width, 0),
        new Point(0, image.Height),
    };
    Rectangle rect = new Rectangle(0, 0, image.Width, image.Height);

    // Make the result bitmap.
    Bitmap bm = new Bitmap(image.Width, image.Height);
    using (Graphics gr = Graphics.FromImage(bm))
    {
        gr.DrawImage(image, points, rect,
            GraphicsUnit.Pixel, attributes);
    }

    // Return the result.
    return bm;
}

The code starts by creating a ColorMatrix object to scale the pixel’s red, green, and blue color components. (I use the variable b instead of brightness so the matrix’s columns line up and make the code easier to read.) The program then creates an ImageAttributes object and uses its SetColorMatrix method to give it the ColorMatrix.

Next the program defines a Point array and a Rectangle to indicate that the entire input image should be drawn on an output area and with its original size. (Some overloaded versions of the Graphics object’s DrawImage method take simpler parameters, but they don’t let you use an ImageAttributes object.)

The program then creates a Bitmap and an associated Graphics object. It uses the Graphics object to draw the input image onto the Bitmap, passing the DrawImage method the ImageAttributes object. DrawImage uses the ImageAttributes object’s ColorMatrix to transform each of the pixels it draws, so the result has scaled brightness.

This method is extremely fast so you can drag the scroll bar back and forth to adjust the brightness in real time.

Some of the following posts demonstrate other interesting uses of the ImageAttributes and ColorMatrix classes. Their most interesting code is similar to the AdjustBrightness method shown here, so you can refer back to this page for details that aren’t covered in those posts.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in graphics, image processing and tagged , , , , , , , , , . Bookmark the permalink.

6 Responses to Use an ImageAttributes object to adjust an image’s brightness in C#

  1. Andrei says:

    Thank you, thank you so much

  2. Chris says:

    Works great, however I had to change the lines
    new Point(image.Width – 1, 0),
    new Point(0, image.Height – 1),
    to remove the minus 1 (-1) as it was causing a black line to appear on the right and bottom. What was the reason for doing this?

  3. Pingback: Use an ImageAttributes to convert an image to sepia toneC# Helper

  4. Pingback: Use an ImageAttributes to convert an image to monochromeC# Helper

  5. Pingback: Adjust image translucency in C# - C# HelperC# Helper

Leave a Reply

Your email address will not be published. Required fields are marked *