12,882,142 members (29,008 online)
alternative version

#### Stats

63.2K views
21 bookmarked
Posted 29 Jul 2004

# Multiple Matrices With ColorMatrix in C#

, 29 Jul 2004
 Rate this:
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);```

A list of licenses authors might use can be found here

## Share

 Web Developer United States
.Net wannabe

## You may also be interested in...

 First Prev Next
 A cleaner code - more versatile Elmue31-Aug-14 11:09 Elmue 31-Aug-14 11:09
 My vote of 5 Member 434321322-Mar-11 23:56 Member 4343213 22-Mar-11 23:56
 Most of this code can be optimised out MikeDC19-Sep-06 16:18 MikeDC 19-Sep-06 16:18
 Re: Most of this code can be optimised out dcoolidge20-Sep-06 7:01 dcoolidge 20-Sep-06 7:01
 DrawImage Performace issue ms44cn5-Sep-06 22:04 ms44cn 5-Sep-06 22:04
 Re: DrawImage Performace issue dcoolidge7-Sep-06 11:07 dcoolidge 7-Sep-06 11:07
 As opposed to what my article is saying, I did end up doing two Graphics.DrawImage. The first DrawImage clips the image to the display. The next DrawImage applies the matrix. If your display area is small this works pretty well. The following code shows how. // Draw the clipped image Rectangle myRec = new Rectangle(0, 0, viewEndX - viewStartX, viewEndY - viewStartY); Bitmap bm = new Bitmap(viewEndX - viewStartX, viewEndY - viewStartY); Graphics g = Graphics.FromImage((Image)bm); g.DrawImage(bigImage, myRec, viewStartX, viewStartY, viewEndX, viewEndY, GraphicsUnit.Pixel); // Apply the filter to the clipped image. Bitmap bm2 = new Bitmap(viewEndX - viewStartX, viewEndY - viewStartY); Graphics g2 = Graphics.FromImage((Image)bm2); System.Drawing.Imaging.ImageAttributes m_ia = new ImageAttributes(); float[][] brightness = GetBrightnessMatrix(m_Brightness, m_Brightness, m_Brightness, 1); float[][] contrast = GetContrastMatrix(m_Contrast); float[][] matrix = Multiply(brightness, contrast); System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(matrix); m_ia.SetColorMatrix(cm); g2.DrawImage(bm, myRec, 0, 0, PIC_WIDTH, PIC_HEIGHT, GraphicsUnit.Pixel , m_ia); // Now the image is in bm2
 Last Visit: 31-Dec-99 18:00     Last Update: 23-Apr-17 10:09 Refresh 1