用颜色变色变换来调整图像的对比度和亮度

 利用winform进行图形图像的预处理时,常常涉及到对一个图形图像的亮度和对比度进行调节,实质就是改变图像每个像素点的RGB值达到相应的效果;从很多资料上找到的都是遍历一幅图像的每个像素点,通过bmp.GetPixel()得到每个像素点的RGB值,通过循环改变每个像素点的RGB值,最后bmp.SetPixel()实现像素的重置;但是当遍历像素点,图像变换的很慢。这是由于每幅图像的像素点非常多,尤其是大的和清晰度高的图像。在运行程序时必须要等待一会儿。但可以运用一种快速的方式:通过4*4或5*5的颜色变换矩阵实现颜色变换;

4*4的变换矩阵如下

Red    0   0    0

0   Green  0   0

0    0   Blue   0

0    0    0   Alpha

如改变一个点(0,255,0,255)(称为颜色矢量)到半透明,则只需将Alpha定为50%,Red=Green=Blue=1;

但是如果在颜色矢量中添加一个虚拟的第五个坐标(例如数字1),则可以将5*5矩阵用于任何组合形式的线性变换和平移。

例:                          

[25 100 100 255 1]  *=[50 100 100 255 1]

                                 

如果一个红色分量的值为A,那么A/255表示该红色成分的饱和度。CDI+用颜色成分的饱和度表示像素么个颜色的值。例如一个像素的RGBA的值为(0,255,0,255),那么颜色成分的饱和度为(0,1,0,1)。换句话说,改变一个颜色成分的值实质就是改变该颜色的饱和度。

在GDI+中可通过ImageAttributes对象的函数SetColorMatrix()来完成颜色矩阵的更改。SetColorMatrix()函数具有如下形式:

ImageAttributes.SetColorMatrix(ColorMatrix   new ColorMatrix);

ImageAttributes.SetColorMatrix(ColorMatrix   new ColorMatrix,ColorMatrixFlag mode);

ImageAttributes.SetColorMatrix(ColorMatrix   new ColorMatrix,ColorMatrixFlag mode,ColorAdjustType type);

下面是我自己改的一个程序,效果比遍历像素点要好很多。

 

 1 public partial class Form1 : Form
 2     {
 3         public Form1()
 4         {
 5             InitializeComponent();
 6         }
 7         Bitmap bmp;
 8         private void button1_Click(object sender, EventArgs e)
 9         {
10             pictureBox1.Visible = true;
11             OpenFileDialog  ofd=new OpenFileDialog();
12             ofd.Filter = "JEPG文件(*.jpg)|*jpg";
13             ofd.ShowDialog();
14             if (ofd.FileName != "")
15             {
16                 bmp = new Bitmap(ofd.FileName);
17                 pictureBox1.Image = bmp;
18                 pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
19             }
20             else
21                 return;
22         }
23 
24         public void SetContrast(float c)
25         {
26             pictureBox1.Visible = false;
27             Bitmap bmp1 = (Bitmap)bmp.Clone();
28             Graphics g = this.CreateGraphics();
29             //g.Clear(Color.White);
30             int width = bmp.Width;
31             int height = bmp.Height;
32             ImageAttributes imageAttributes = new ImageAttributes();
33             if (c < -100) c = -100;
34             if (c >  100) c =  100;
35             c = (100.0f + c) / 100.0f;
36             c *= c;
37             float[][] colorMatrixElements =
38             {
39                 new float[]{c,0.0f,0.0f,0.0f,0.0f},
40                 new float[]{0.0f,c,0.0f,0.0f,0.0f},
41                 new float[]{0.0f,0.0f,c,0.0f,0.0f},
42                 new float[]{0.0f,0.0f,0.0f,1.0f,0.0f},
43                 new float[]{0.5f-0.5f*c,0.5f-0.5f*c,0.5f-0.5f*c,0.0f,1.0f}
44             };
45             ColorMatrix colorMatrix=new ColorMatrix (colorMatrixElements);
46             imageAttributes.SetColorMatrix(colorMatrix,
47                 ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
48             this.Refresh();
49             g.DrawImage(bmp1, new Rectangle(pictureBox1.Location.X,pictureBox1.Location.Y,
50                 pictureBox1.Width, pictureBox1.Height), 0, 0,
51                 width, height,
52                 GraphicsUnit.Pixel, imageAttributes);
53             pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
54             
55         }
56 
57         private void button2_Click(object sender, EventArgs e)
58         {
59             SetContrast(65);
60         }
61 
62         private void Form1_Paint(object sender, PaintEventArgs e)
63         {
64             button1.Enabled = true;
65             button2.Enabled = true;
66         }
67 
68         private void Form1_Load(object sender, EventArgs e)
69         {
70 
71         }
72 
73  
74     }

 

posted on 2016-11-08 20:10  指尖&流沙  阅读(382)  评论(0编辑  收藏  举报

导航