用颜色变色变换来调整图像的对比度和亮度
利用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 }