今年学习了多媒体课程,其中有这样一个试验:多媒体图像处理(图像变换、灰度处理、颜色变化等),当时没有细想,直接使用了像素的变换进行处理,就是使用这样一种方法:使用二重循环,分别循环对图片的每一个像素点进行处理,如灰度处理是:
R=(R+G+B)/3
G=(R+G+B)/3
B=(R+G+B)/3
另外还有一个分量A,这个仅在图像透明方面进行处理,这里不在赘述。但是最近看了一些GDI+方面的书,因此发现了一个特别的方法进行处理(使用ImageAttributes和ColorMatrix)。
一、原来的方法-----循环对像素进行处理
代码如下:
Bitmap bitmap = new Bitmap(picBox.Image);
Graphics g = Graphics.FromImage(bitmap);
for (int w = 0; w < bitmap.Width; w++)
{
for (int h = 0; h < bitmap.Height; h++)
{
Color cc = bitmap.GetPixel(w, h);
int r = (cc.R + cc.G + cc.B) / 3;
bitmap.SetPixel(w, h, Color.FromArgb(r, r, r));
}
}
g.DrawImage(bitmap, 0, 0);
picBox.Image = bitmap;
g.Dispose();
这种方法的缺点就是速度问题,因为图片如果很大,循环的次数就是:bitmap.Width*bitmap.Height。
二、新方法----使用ImageAttributes和ColorMatrix
ColorMatrix是一个颜色矩阵,使用的是5*5的矩阵,其中颜色的5个分量是:
Red通道,
Green通道,
Blue通道,
Alpha通道,
灰度
因此根据线形代数中的矩阵变换知识,可得如下:
┏A01 A01 A02 A03 A04┓
┃A10 A11 A12 A13 A14┃
[R G B A W]=[R G B A W]┃A20 A21 A22 A23 A24┃
┃A30 A31 A32 A33 A34┃
┗A40 A41 A42 A43 A44┛
这样很容易就知道了颜色变化的方法和结构,而且灰度处理的方法是:
R*0.299+G*0.587+B*0.114
因此设置变换矩阵为:
┏0.299 0.299 0.299 0 0┓
┃0.587 0.587 0.587 0 0┃
┃0.114 0.114 0.114 0 0┃
┃0 0 0 1 0┃
┗0 0 0 0 1┛
代码如下:
Bitmap bitmap = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bitmap))
{
ImageAttributes imageAttributes = new ImageAttributes();
float[][] Matrix = {
new float[] {0.299f,0.299f, 0.299f, 0, 0},
new float[] {0.587f, 0.587f, 0.587f, 0, 0},
new float[] {0.114f, 0.114f, 0.114f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}};
ColorMatrix colorMatrix = new ColorMatrix(Matrix);
imageAttributes.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap
);
g.DrawImage(
bitmap,
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
0,
0,
bitmap.Width,
bitmap.Height,
GraphicsUnit.Pixel,
imageAttributes
);
picBox.Image = bitmap;
}
这种方法速度十分快,我认为是最好的方法,其他变换方法也是如此,不再赘述。
R=(R+G+B)/3
G=(R+G+B)/3
B=(R+G+B)/3
另外还有一个分量A,这个仅在图像透明方面进行处理,这里不在赘述。但是最近看了一些GDI+方面的书,因此发现了一个特别的方法进行处理(使用ImageAttributes和ColorMatrix)。
一、原来的方法-----循环对像素进行处理
代码如下:
Bitmap bitmap = new Bitmap(picBox.Image);
Graphics g = Graphics.FromImage(bitmap);
for (int w = 0; w < bitmap.Width; w++)
{
for (int h = 0; h < bitmap.Height; h++)
{
Color cc = bitmap.GetPixel(w, h);
int r = (cc.R + cc.G + cc.B) / 3;
bitmap.SetPixel(w, h, Color.FromArgb(r, r, r));
}
}
g.DrawImage(bitmap, 0, 0);
picBox.Image = bitmap;
g.Dispose();
这种方法的缺点就是速度问题,因为图片如果很大,循环的次数就是:bitmap.Width*bitmap.Height。
二、新方法----使用ImageAttributes和ColorMatrix
ColorMatrix是一个颜色矩阵,使用的是5*5的矩阵,其中颜色的5个分量是:
Red通道,
Green通道,
Blue通道,
Alpha通道,
灰度
因此根据线形代数中的矩阵变换知识,可得如下:
┏A01 A01 A02 A03 A04┓
┃A10 A11 A12 A13 A14┃
[R G B A W]=[R G B A W]┃A20 A21 A22 A23 A24┃
┃A30 A31 A32 A33 A34┃
┗A40 A41 A42 A43 A44┛
这样很容易就知道了颜色变化的方法和结构,而且灰度处理的方法是:
R*0.299+G*0.587+B*0.114
因此设置变换矩阵为:
┏0.299 0.299 0.299 0 0┓
┃0.587 0.587 0.587 0 0┃
┃0.114 0.114 0.114 0 0┃
┃0 0 0 1 0┃
┗0 0 0 0 1┛
代码如下:
Bitmap bitmap = new Bitmap(picBox.Image);
using (Graphics g = Graphics.FromImage(bitmap))
{
ImageAttributes imageAttributes = new ImageAttributes();
float[][] Matrix = {
new float[] {0.299f,0.299f, 0.299f, 0, 0},
new float[] {0.587f, 0.587f, 0.587f, 0, 0},
new float[] {0.114f, 0.114f, 0.114f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}};
ColorMatrix colorMatrix = new ColorMatrix(Matrix);
imageAttributes.SetColorMatrix(
colorMatrix,
ColorMatrixFlag.Default,
ColorAdjustType.Bitmap
);
g.DrawImage(
bitmap,
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
0,
0,
bitmap.Width,
bitmap.Height,
GraphicsUnit.Pixel,
imageAttributes
);
picBox.Image = bitmap;
}
这种方法速度十分快,我认为是最好的方法,其他变换方法也是如此,不再赘述。