C#实现彩色图像灰度处理
2012-06-04 11:14
696 查看
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace ImageGray { public partial class Form1 : Form { private TimePerform myperform; public Form1() { InitializeComponent(); myperform = new TimePerform(); } private string curFileName; private System.Drawing.Bitmap curBitmap; //打开图像 private void open_Click(object sender, EventArgs e) { OpenFileDialog opdlg = new OpenFileDialog(); opdlg.Filter = "所有图像文件|*.bmp;*.pcx;*.png;*.jpg;*.gif" + "*.tif;*.ico;*.dxf;*.wmf;*.eps;*.emf|" + "位图(*.bmp;*.jpg;*.png;...)|*.bmp;*.pcx;*.jpg;*.png;*.jpg;*.gif;*.tif;*.ico|" + "矢量图(*.wmf;*.eps;*.emf...)|*.dxf;*.cgm;*.cgr;*.wmf;*.eps;*.emf"; opdlg.Title = "打开图像文件"; opdlg.ShowHelp = true; if (opdlg.ShowDialog() == DialogResult.OK) { curFileName = opdlg.FileName; try { curBitmap = (Bitmap)Image.FromFile(curFileName); } catch(Exception ee){ MessageBox.Show(ee.Message); } } Invalidate(); } //保存图像 private void save_Click(object sender, EventArgs e) { if (curBitmap == null) return; SaveFileDialog savedlg = new SaveFileDialog(); savedlg.Title = "保存为"; savedlg.ShowHelp = true; savedlg.Filter = "bmp文件(*.bmp)|*.bmp|"+"gif文件(*.gif)|*.gif|"+"jpeg文件(*.jpg)|*.jpg|"+"png文件(*.png)|*.png"; if (savedlg.ShowDialog() ==DialogResult.OK) { string filename = savedlg.FileName; string suffix = filename.Remove(0, filename.Length - 3); switch(suffix) { case "bmp": curBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp); break; case "gif": curBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Gif); break; case "jpg": curBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg); break; case "png": curBitmap.Save(filename, System.Drawing.Imaging.ImageFormat.Png); break; default: break; } } } //关闭窗体 private void close_Click(object sender, EventArgs e) { this.Close(); } //利用与窗体相关联的Graphics对象绘制图像 private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; if (curBitmap != null) { g.DrawImage(curBitmap,160,20,curBitmap.Width,curBitmap.Height); } } /// <summary> /// 彩色图像灰度化 在图像处理算法中,要把彩色图像转换成灰度图像 /// 24位彩色图象用3个字节表示,每个字节对应着R,G,B分量的亮度。当R G B 不同时表现为彩色图像 /// 当R G B相同时表现为灰度图像 /// Gray(i,j)=[0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j)]/3 /// 变换后的灰度图像仍然用24位图像表示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> /// 方法一:提取像素法 使用GDI+中的Bitmap.GetPixel和Bitmap.SetPixel private void pixel_Click(object sender, EventArgs e) { myperform.Start(); if (curBitmap != null) { Color color; int ret; for(int i=0;i<curBitmap.Width;i++) { for (int j = 0; j < curBitmap.Height;j++ ) { color = curBitmap.GetPixel(i, j); ret=(int)(color.R*0.299+color.G*0.587+color.B*0.114); curBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret)); } } myperform.Stop(); textBox1.Text = myperform.Duration.ToString("####.##" + "毫秒"); Invalidate();//对窗体进行重新绘制,这将强制执行Paint事件处理程序 } } // 方法二:内存法,把图像数据直接复制到内存中,提高程序的运行速度 private void memory_Click(object sender, EventArgs e) { myperform.Start(); if (curBitmap != null) { Rectangle rect = new Rectangle(0,0,curBitmap.Width,curBitmap.Height); System.Drawing.Imaging.BitmapData bmpdata = curBitmap.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,curBitmap.PixelFormat); IntPtr ptr = bmpdata.Scan0; int bytes = curBitmap.Width * curBitmap.Height * 3; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr,rgbValues,0,bytes); double colorTemp = 0; for (int i = 0; i < rgbValues.Length;i+=3 ) { colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114; rgbValues[i]=rgbValues[i+1]=rgbValues[i+2]=(byte)colorTemp; } System.Runtime.InteropServices.Marshal.Copy(rgbValues,0,ptr,bytes); curBitmap.UnlockBits(bmpdata); myperform.Stop(); textBox1.Text = myperform.Duration.ToString("####.##" + "毫秒"); Invalidate(); } } //方法三:指针法,直接使用指针对位图进行操作,使用unsafe关键字时,需在项目-属性-生成-允许不安全代码进行勾选 private void pointer_Click(object sender, EventArgs e) { myperform.Start(); if (curBitmap != null) { Rectangle rect = new Rectangle(0,0,curBitmap.Width,curBitmap.Height); System.Drawing.Imaging.BitmapData bmpdata = curBitmap.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,curBitmap.PixelFormat); byte temp=0; unsafe { byte* ptr = (byte*)(bmpdata.Scan0); for (int i = 0; i < bmpdata.Height;i++ ) { for (int j = 0; j < bmpdata.Width; j++) { temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]); ptr[0]=ptr[1]=ptr[2]=temp; ptr += 3; } ptr += bmpdata.Stride - bmpdata.Width * 3; } } curBitmap.UnlockBits(bmpdata); myperform.Stop(); textBox1.Text = myperform.Duration.ToString("####.##" + "毫秒"); Invalidate(); } } } }//三种算法的时间比较
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Runtime.InteropServices; using System.ComponentModel; namespace ImageGray { class TimePerform {[DllImport("Kernel32.dll")] //这叫引入kernel32.dll这个动态连接库。这个动态连接库里面包含了很多WindowsAPI函数,如果你想使用这面的函数,就需要这么引入。 //举个例子://[DllImport("kernel32.dll")] //private static extern void 函数名(参数,[参数]); 函数名就是一个属于kernel32.dll里的一个函数。完了你就可以用那个函数了 //extern 修饰符用于声明在外部实现的方法。 extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 特性一起使用。 在这种情况下,还必须将方法声明为 static private static extern bool QueryPerformanceCounter(out long lpPerformanceCount) ; [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency); private long startTime, stopTime; private long freq; public TimePerform() { startTime = 0; stopTime = 0; if (QueryPerformanceFrequency(out freq)==false) { throw new Win32Exception(); } } public void Start() { Thread.Sleep(0); QueryPerformanceCounter(out startTime); } public void Stop() { QueryPerformanceCounter(out stopTime); } public double Duration { get{return (double)(stopTime-startTime)*1000/ (double)freq;} } } }
相关文章推荐
- 图形图像处理-之-彩色转化到灰度的速度优化
- 数字图像处理基础:教你如何区分单色图像、灰度图像、伪彩色图像、真彩色图像
- 图形图像处理-之-彩色转化到灰度的速度优化
- VC编程实现灰度图像与彩色图像的相互转换
- C# 图像处理:实现鼠标选择矩形截图
- Atitit 图像处理 灰度图片 灰度化的原理与实现
- 数字图像处理基本算法实现(1)--section3.2基本灰度变换
- 图形图像处理-之-彩色转化到灰度的速度优化
- Matlab中图像处理实例:灰度变换,空域滤波,频域滤波,傅里叶变换的实现
- Opencv实现图像的灰度处理,二值化,阀值选择
- Atitit 图像处理 灰度图片 灰度化的原理与实现
- 本图片处理类功能非常之强大可以实现几乎所有WEB开发中对图像的处理功能都集成了,包括有缩放图像、切割图像、图像类型转换、彩色转黑白、文字水印、图片水印等功能
- PhotoShop算法实现--伪彩色图像处理(八)
- 图像处理中几个基本的处理方法c#代码实现
- 【VS开发】【图像处理】基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果
- Opencv实现图像的灰度处理,二值化,阀值选择
- C# 图像处理:将图像(24位真彩)转为 8位灰度图像 采用了内存法,大大提高了效率
- Win8 Metro(C#)数字图像处理--2.75灰度图像的形态学算法
- RGB彩色图像与灰度图像转换 opencv实现 代码及分析
- OpenCV实现彩色图像转换为灰度图及二值化处理