图像

  • 格式:doc
  • 大小:52.00 KB
  • 文档页数:8

C#图像处理前段时间在写一个公司层级动态呈现的图形处理功能,对C#的图形处理有了大致的了解,现整理如下:一、生成图片并实现颜色渐变效果Response.Clear();Bitmap imgOutput = new Bitmap(100, 50);Graphics gic = Graphics.FromImage(imgOutput);gic.Clear(Color.BlueViolet);gic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;gic.DrawString("渐变图形", new Font("黑体",16,FontStyle.Italic),new SolidBrush(Color.White),new PointF(2,2));gic.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0,0), new Point(100,50), Color.FromArgb(0,0,0,0),Color.FromArgb(255,255,255,255)),0,0,100,50);imgOutput.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg);gic.Dispose();imgOutput.Dispose();Response.End();二、对图片进行反转System.Drawing.Image drawimage = System.Drawing.Image.FromFile(photopath);//photopath表示图片的物理地址drawimage.RotateFlip(RotateFlipType.Rotate270FlipNone);if(File.Exists(photopath)){File.SetAttributes(photopath,FileAttributes.Normal);File.Delete(photopath);}drawimage.Save(photopath,System.Drawing.Imaging.ImageFormat.Jpeg);drawimage.Dispose();三、对图片进行缩放System.Drawing.Image drawimage = System.Drawing.Image.FromFile(photopath);Bitmap imgOutput = new Bitmap(drawimage,60,30);imgOutput.Save(newphotppath, System.Drawing.Imaging.ImageFormat.Jpeg);imgOutput.Dispose();Response.End();其他还有一些画线、画矩形、画圆等的函数和方法都可以在System.Drawing中找到;本文的实例是一个数字图像处理的应用程序,它完成的功能包括对图像颜色的翻转、对图像进行灰度处理和对图像进行增亮处理。

该程序对图像进行处理部分的代码包含在一个专门的Filters类里面,通过调用该类里的静态成员函数,我们就可以实现相应的图像处理功能了。

为实现图像处理,我们要对图像进行逐个象素处理。

我们知道图像是由一个个的象素点组成的,对一幅图像的每个象素进行了相应的处理,最后整个图像也就处理好了。

在这个过程中,我们只需对每个象素点进行相应的处理,在处理过程中却不需要考虑周围象素点对其的影响,所以相对来说程序的实现就变得简单多了。

由于GDI+中的BitmapData类不提供对图像内部数据的直接访问的方法,我们唯一的办法就是使用指针来获得图像的内部数据,这时我们就得运用unsafe这个关键字来指明函数中访问图像内部数据的代码块了。

在程序中,我还运用了打开文件和保存文件等选项,以使我们的辛勤劳动不付之东流。

二.程序的实现:1.打开Visual ,新建一个Visual C#的项目,在模板中选择"Windows 应用程序"即可,项目名称可自定(这里为ImageProcessor)。

2.为使窗体能显示图像,我们需要重载窗体的OnPaint()事件函数,在该函数中我们将一个图像绘制在程序的主窗体上,为了使窗体能显示不同尺寸大小的图像,我们还将窗体的AutoScroll属性设置为true。

这样,根据图像的尺寸,窗体两边就会出现相应的滚动条。

该函数的实现如下:private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e){Graphics g = e.Graphics;g.DrawImage(m_Bitmap, new Rectangle(this.AutoScrollPosition.X, this.AutoScrollPosition.Y, (int)(m_Bitmap.Width), (int)(m_Bitmap.Height)));}3.给主窗体添加一个主菜单,该主菜单完成了一些基本的操作,包括"打开文件"、"保存文件"、"退出"、"翻转操作"、"灰度操作"、"增亮操作"等。

前面三个操作完成图像文件的打开和保存以及程序的退出功能,相应的事件处理函数如下:private void menuItemOpen_Click(object sender, System.EventArgs e){OpenFileDialog openFileDialog = new OpenFileDialog();openFileDialog.Filter = "Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp/*.jpg)|*.bmp/*.jpg";openFileDialog.FilterIndex = 2 ;openFileDialog.RestoreDirectory = true ;if(DialogResult.OK == openFileDialog.ShowDialog()){m_Bitmap = (Bitmap)Bitmap.FromFile(openFileDialog.FileName, false);this.AutoScroll = true;this.AutoScrollMinSize=new Size ((int)(m_Bitmap.Width),(int)m_Bitmap.Height));this.Invalidate();}}其中,m_Bitmap为主窗体类的一个数据成员,声明为private System.Drawing.Bitmap m_Bitmap;(注:因为程序中用到了相关的类,所以在程序文件的开始处应添加using System.Drawing.Imaging;)同时,在该类的构造函数中,我们必须先给它new一个Bitmap 对象:m_Bitmap = new Bitmap(2,2);上述代码中的this.Invalidate();完成主窗体的重绘工作,它调用了主窗体的OnPaint()函数,结果就将打开的图像文件显示在主窗体上。

private void menuItemSave_Click(object sender, System.EventArgs e){SaveFileDialog saveFileDialog = new SaveFileDialog();saveFileDialog.Filter = "Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp/*.jpg)|*.bmp/*.jpg";saveFileDialog.FilterIndex = 1 ;saveFileDialog.RestoreDirectory = true ;if(DialogResult.OK == saveFileDialog.ShowDialog()){m_Bitmap.Save(saveFileDialog.FileName);}}其中m_Bitmap.Save(saveFileDialog.FileName);一句完成了图像文件的保存,正是运用了GDI+的强大功能,我们只需这么一条简单的语句就完成了以前很大工作量的任务,所以合理运用.NET中的新机制一定会大大简化我们的工作的。

private void menuItemExit_Click(object sender, System.EventArgs e){this.Close();}接下来,三个主要操作的事件处理函数如下:private void menuItemInvert_Click(object sender, System.EventArgs e){if(Filters.Invert(m_Bitmap))this.Invalidate();}private void menuItemGray_Click(object sender, System.EventArgs e){if(Filters.Gray(m_Bitmap))this.Invalidate();}private void menuItemBright_Click(object sender, System.EventArgs e){Parameter dlg = new Parameter();dlg.nValue = 0;if (DialogResult.OK == dlg.ShowDialog()){if(Filters.Brightness(m_Bitmap, dlg.nValue))this.Invalidate();}}三个函数中分别调用了相应的图像处理函数Invert()、Gray()、Brightness()等三个函数。

这三个函数Filters类中的三个类型为public的静态函数(含有static关键字),它们的返回值类型均是bool型的,根据返回值我们可以决定是否进行主窗体的重绘工作。

Invert()、Gray()、Brightness()等三个函数均包含在Filters类里面,Invert()函数的算法如下:public static bool Invert(Bitmap b){BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);int stride = bmData.Stride;System.IntPtr Scan0 = bmData.Scan0;unsafe{byte * p = (byte *)(void *)Scan0;int nOffset = stride - b.Width*3;int nWidth = b.Width * 3;for(int y=0;y<b.Height;++y){for(int x=0; x < nWidth; ++x ){p[0] = (byte)(255-p[0]);++p;}p += nOffset;}}b.UnlockBits(bmData);return true;}该函数以及后面的函数的参数都是Bitmap类型的,它们传值的对象就是程序中所打开的图像文件了。