65.9K
CodeProject is changing. Read more.
Home

Multiple Matrices With ColorMatrix in C#

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.40/5 (8 votes)

Jul 30, 2004

viewsIcon

80985

downloadIcon

1575

Using multiple matrices to manipulate an image.

Introduction

In my current job, I was creating a control that manipulated the brightness and contrast of an image. I didn't want to call Graphics.DrawImage more than once. The solution was to do a matrix multiply on the two matrices (brightness and contrast) before drawing the image. Just for fun, I included a picture of my daughter in the project...

The main part of the code I wanted to share was the matrices and the matrix multiplication.

private void NewMatrices()
{
  // Initialize the matices;
  bm = new float[5][];
  cm = new float[5][];
  for (int i = 0; i < 5; i++)
  {
    bm[i] = new float[5];
    cm[i] = new float[5];
  }
  // Set the values of the brightness matrix
  float brightness = 0.2f;
  bm[0][0] = 1; bm[0][1] = 0; bm[0][2] = 0; bm[0][3] = 0; bm[0][4] = 0;
  bm[1][0] = 0; bm[1][1] = 1; bm[1][2] = 0; bm[1][3] = 0; bm[1][4] = 0;
  bm[2][0] = 0; bm[2][1] = 0; bm[2][2] = 1; bm[2][3] = 0; bm[2][4] = 0;
  bm[3][0] = 0; bm[3][1] = 0; bm[3][2] = 0; bm[3][3] = 1; bm[3][4] = 0;
  bm[4][0] = brightness; bm[4][1] = brightness;
  bm[4][2] = brightness; bm[4][3] = 1; bm[4][4] = 1;
  // Set the values of contrast matrix
  float contrast = 20f;
  float T = 0.5f * (1f - contrast);
  cm[0][0] = contrast; cm[0][1] = 0; cm[0][2] = 0; cm[0][3] = 0; cm[0][4] = 0;
  cm[1][0] = 0; cm[1][1] = contrast; cm[1][2] = 0; cm[1][3] = 0; cm[1][4] = 0;
  cm[2][0] = 0; cm[2][1] = 0; cm[2][2] = contrast; cm[2][3] = 0; cm[2][4] = 0;
  cm[3][0] = 0; cm[3][1] = 0; cm[3][2] = 0; cm[3][3] = 1; cm[3][4] = 0;
  cm[4][0] = T; cm[4][1] = T; cm[4][2] = T; cm[4][3] = 1; cm[4][4] = 1;
}

private float[][] Multiply(float[][] f1, float[][] f2)
{
  float[][] X = new float[5][];
  for (int d = 0; d < 5; d++)
    X[d] = new float[5];
  int size = 5;
  float[] column = new float[5];
  for (int j = 0; j < 5; j++)
  {
    for (int k = 0; k < 5; k++)
    {
      column[k] = f1[k][j];
    }
    for (int i = 0; i < 5; i++)
    {
      float[] row = f2[i];
      float s = 0;
      for (int k = 0; k < size; k++)
      {
        s += row[k] * column[k];
      }
      X[i][j] = s;
    } 
  }
  return X;
}

Another interesting part of the code is the DrawImage function. It takes in a matrix (i.e., float[][]) and draws an image with that matrix.

private void DrawImage(float[][] Matrix)
{
  ColorMatrix m = new ColorMatrix(Matrix);
  ImageAttributes ia = new ImageAttributes();
  ia.SetColorMatrix(m);
  Rectangle rMy = new Rectangle(0,0,i.Width, i.Height);
  Bitmap bm = new Bitmap(i.Width, i.Height);
  Graphics g = Graphics.FromImage((Image)bm);
  g.Clear(Color.Black);
  g.DrawImage(i, rMy, 0, 0, i.Width, i.Height, 
                               GraphicsUnit.Pixel, ia);
  pictureBox1.Image = (Image)bm;
}

So now, we can call DrawImage with one of our matrices we created above, or use Multiply to combine them.

DrawImage(cm);
DrawImage(bm);
DrawImage(Multiply(cm,bm);