C#
      
      
       图像处理
      
     
    
   
    
     
      
       (各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)
      
     
    
   
    
    
   
    
     
      一、各种旋转、改变大小
     
    
   
    
     注意:先要添加画图相关的using引用。
    
   
    
     //向右旋转图像90°代码如下:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);//加载图像
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);//填充窗体背景为白色
     
     Point[] destinationPoints = {
     
     
     new Point(100, 0), // destination for upper-left point of original
     
     new Point(100, 100),// destination for upper-right point of original
     
     new Point(0, 0)}; // destination for lower-left point of original
     
     g.DrawImage(bmp, destinationPoints);
    
   
    
     }
    
   
    
     
     //旋转图像180°代码如下:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);
     
     Point[] destinationPoints = {
     
     
     new Point(0, 100), // destination for upper-left point of original
     
     new Point(100, 100),// destination for upper-right point of original
     
     new Point(0, 0)}; // destination for lower-left point of original
     
     g.DrawImage(bmp, destinationPoints);
    
   
    
     }
    
   
    
     
     //图像切变代码:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);
     
     Point[] destinationPoints = {
     
     
     new Point(0, 0), // destination for upper-left point of original
     
     new Point(100, 0), // destination for upper-right point of original
     
     new Point(50, 100)};// destination for lower-left point of original
     
     g.DrawImage(bmp, destinationPoints);
    
   
    
     }
    
   
    
     
     //图像截取:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);
     
     Rectangle sr = new Rectangle(80, 60, 400, 400);//要截取的矩形区域
     
     Rectangle dr = new Rectangle(0, 0, 200, 200);//要显示到Form的矩形区域
     
     g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);
    
   
    
     }
    
   
    
     
     //改变图像大小:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);
     
     int width = bmp.Width;
     
     int height = bmp.Height;
     
     // 改变图像大小使用低质量的模式
     
     g.InterpolationMode = InterpolationMode.NearestNeighbor;
     
     g.DrawImage(bmp, new Rectangle(10, 10, 120, 120), // source rectangle
    
   
    
     new Rectangle(0, 0, width, height), // destination rectangle
     
     GraphicsUnit.Pixel);
     
     // 使用高质量模式
     
     //g.CompositingQuality = CompositingQuality.HighSpeed;
     
     g.InterpolationMode = InterpolationMode.HighQualityBicubic;
     
     g.DrawImage(
     
     bmp,
     
     new Rectangle(130, 10, 120, 120),
     
     new Rectangle(0, 0, width, height),
     
     GraphicsUnit.Pixel);
    
   
    
     }
    
   
    
     
     //设置图像的分辩率:
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Bitmap bmp = new Bitmap(“rama.jpg”);
     
     g.FillRectangle(Brushes.White, this.ClientRectangle);
     
     bmp.SetResolution(300f, 300f);
     
     g.DrawImage(bmp, 0, 0);
     
     bmp.SetResolution(1200f, 1200f);
     
     g.DrawImage(bmp, 180, 0);
    
   
    
     }
    
   
    
     
     //用GDI+画图
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics gForm = e.Graphics;
     
     gForm.FillRectangle(Brushes.White, this.ClientRectangle);
     
     for (int i = 1; i <= 7; ++i)
     
     {
     
    
   
    
     //在窗体上面画出橙色的矩形
    
   
    
     Rectangle r = new Rectangle(i*40-15, 0, 15,
     
     this.ClientRectangle.Height);
     
     gForm.FillRectangle(Brushes.Orange, r);
    
   
    
     }
    
   
    
     //在内存中创建一个Bitmap并设置CompositingMode
     
     Bitmap bmp = new Bitmap(260, 260,
    
   
    
     System.Drawing.Imaging.PixelFormat.Format32bppArgb);
     
     Graphics gBmp = Graphics.FromImage(bmp);
     
     gBmp.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
     
     // 创建一个带有Alpha的红色区域
     
     // 并将其画在内存的位图里面
     
     Color red = Color.FromArgb(0x60, 0xff, 0, 0);
     
     Brush redBrush = new SolidBrush(red);
     
     gBmp.FillEllipse(redBrush, 70, 70, 160, 160);
     
     // 创建一个带有Alpha的绿色区域
     
     Color green = Color.FromArgb(0x40, 0, 0xff, 0);
     
     Brush greenBrush = new SolidBrush(green);
     
     gBmp.FillRectangle(greenBrush, 10, 10, 140, 140);
     
     //在窗体上面画出位图 now draw the bitmap on our window
     
     gForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height);
     
     // 清理资源
     
     bmp.Dispose();
     
     gBmp.Dispose();
     
     redBrush.Dispose();
     
     greenBrush.Dispose();
    
   
    
     }
    
   
    
     
     //在窗体上面绘图并显示图像
     
     private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
     
     {
     
    
   
    
     Graphics g = e.Graphics;
     
     Pen blackPen = new Pen(Color.Black, 1);
    
   
    
     if (ClientRectangle.Height / 10 > 0)
    
   
    
     {
     
    
   
    
     for (int y = 0; y < ClientRectangle.Height; y += ClientRectangle.Height / 10)
    
   
    
     {
     
    
   
    
     g.DrawLine(blackPen, new Point(0, 0), new Point(ClientRectangle.Width, y));
    
   
    
     }
    
   
    
     }
    
   
    
     blackPen.Dispose();
    
   
    
     }
    
   
    
    
   
    
     
      C# 使用Bitmap类进行图片裁剪
     
    
   
    
    
   
    
     在Mapwin(手机游戏地图编辑器)生成的地图txt文件中添加自己需要处理的数据后转换成可在手机(Ophone)开发环境中使用的字节流地图文件的小工具,其中就涉及到图片的裁剪和生成了。有以下几种方式。
    
   
    
    
   
    
     
      方法一:拷贝像素。
     
    
   
    
     
     
    
   
    
     当然这种方法是最笨的,效率也就低了些。
    
   
    
     在Bitmap类中我们可以看到这样两个方法:GetPixel(int x, int y)和SetPixel(int x, int y, Color color)方法。从字面的含以上就知道前者是获取图像某点像素值,是用Color对象返回的;后者是将已知像素描画到制定的位置。
    
   
    
     下面就来做个实例检验下:
    
   
    
     1.首先创建一个Windows Form窗体程序,往该窗体上拖放7个PictureBox控件,第一个用于放置并显示原始的大图片,其后6个用于放置并显示裁剪后新生成的6个小图;
    
   
    
     2.放置原始大图的PictureBox控件name属性命名为pictureBoxBmpRes,其后pictureBox1到pictureBox6依次命名,并放置在合适的位置;
    
   
    
     3.双击Form窗体,然后在Form1_Load事件中加入下面的代码即可。
    
   
    
     //导入图像资源
    
   
    
     Bitmap bmpRes = null;
    
   
    
     String strPath = Application.ExecutablePath;
    
   
    
     try{
     
    
   
    
     int nEndIndex = strPath.LastIndexOf(‘//’);
    
   
    
     strPath = strPath.Substring(0,nEndIndex) + “//Bmp//BmpResMM.bmp”;
    
   
    
     bmpRes = new Bitmap(strPath);
    
   
    
    
   
    
     //窗体上显示加载图片
    
   
    
     pictureBoxBmpRes.Width = bmpRes.Width;
    
   
    
     pictureBoxBmpRes.Height = bmpRes.Height;
    
   
    
     pictureBoxBmpRes.Image = bmpRes;
    
   
    
     }
    
   
    
     catch(Exception ex)
    
   
    
     {
     
    
   
    
     System.Windows.Forms.MessageBox.Show(“图片资源加载失败!/r/n” + ex.ToString());
    
   
    
     }
    
   
    
    
   
    
     //裁剪图片(裁成2行3列的6张图片)
    
   
    
     int nYClipNum = 2, nXClipNum = 3;
    
   
    
     Bitmap[] bmpaClipBmpArr = new Bitmap[nYClipNum * nXClipNum];
    
   
    
     for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)
    
   
    
     {
     
    
   
    
     for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)
    
   
    
     {
     
    
   
    
     int nClipWidth = bmpRes.Width / nXClipNum;
    
   
    
     int nClipHight = bmpRes.Height / nYClipNum;
    
   
    
     int nBmpIndex = nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0?1:0);
    
   
    
     bmpaClipBmpArr[nBmpIndex] = new Bitmap(nClipWidth, nClipHight);
    
   
    
    
   
    
     for(int nY = 0; nY < nClipHight; nY++)
    
   
    
     {
     
    
   
    
     for(int nX = 0; nX < nClipWidth; nX++)
    
   
    
     {
     
    
   
    
     int nClipX = nX + nClipWidth * nXClipNumIndex;
    
   
    
     int nClipY = nY + nClipHight * nYClipNumIndex;
    
   
    
     Color cClipPixel = bmpRes.GetPixel(nClipX, nClipY);
    
   
    
     bmpaClipBmpArr[nBmpIndex].SetPixel(nX, nY, cClipPixel);
    
   
    
     }
    
   
    
     }
    
   
    
     }
    
   
    
     }
    
   
    
     PictureBox[] picbShow = new PictureBox[nYClipNum * nXClipNum];
    
   
    
     picbShow[0] = pictureBox1;
    
   
    
     picbShow[1] = pictureBox2;
    
   
    
     picbShow[2] = pictureBox3;
    
   
    
     picbShow[3] = pictureBox4;
    
   
    
     picbShow[4] = pictureBox5;
    
   
    
     picbShow[5] = pictureBox6;
    
   
    
     for (int nLoop = 0; nLoop < nYClipNum * nXClipNum; nLoop++)
    
   
    
     {
     
    
   
    
     picbShow[nLoop].Width = bmpRes.Width / nXClipNum;
    
   
    
     picbShow[nLoop].Height = bmpRes.Height / nYClipNum;
    
   
    
     picbShow[nLoop].Image = bmpaClipBmpArr[nLoop];
    
   
    
     }
    
   
    
     现在看看那些地方需要注意的了。其中
    
   
    
     int nBmpIndex =
    
   
    
     nXClipNumIndex + nYClipNumIndex * nYClipNum +
     
      (nYClipNumIndex > 0?1:0);
     
    
   
    
     这句定义了存储裁剪图片对象在数组中的索引,需要注意的就是后面的(nYClipNumIndex > 0?1:0)——因为只有当裁剪的对象处于第一行以外的行时需要将索引加1;
    
   
    
     另外,因为这种方法的效率不高,程序运行起来还是顿了下。如果有兴趣的话,可以将以上的代码放到一个按钮Click事件函数中,当单击该按钮时就可以感觉到了。
    
   
    
    
   
    
     
      方法二:运用Clone函数局部复制。
     
    
   
    
     
     
    
   
    
     同样在Bitmap中可以找到Clone()方法,该方法有三个重载方法。Clone(),Clone(Rectangle, PixelFormat)和Clone(RectangleF, PixelFormat)。第一个方法将创建并返回一个精确的实例对象,后两个就是我们这里需要用的局部裁剪了(其实后两个方法本人觉得用法上差不多)。
    
   
    
     将上面的程序稍稍改进下——将裁剪的处理放到一个按钮事件函数中,然后再托一个按钮好窗体上,最后将下面的代码复制到该按钮的事件函数中。
    
   
    
     for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)
    
   
    
     {
     
    
   
    
     for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)
    
   
    
     {
     
    
   
    
     int nClipWidth = bmpRes.Width / nXClipNum;
    
   
    
     int nClipHight = bmpRes.Height / nYClipNum;
    
   
    
     int nBmpIndex =
    
   
    
     nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0 ? 1 : 0);
    
   
    
    
   
    
     Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,
    
   
    
     nClipHight * nYClipNumIndex,
    
   
    
     nClipWidth,
    
   
    
     nClipHight);
    
   
    
    
   
    
     bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);
    
   
    
     }
    
   
    
     }
    
   
    
    
   
    
     运行程序,单击按钮检验下,发现速度明显快可很多。
    
   
    
     其实这种方法较第一中方法不同的地方仅只是变换了for循环中的拷贝部分的处理,
    
   
    
     Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,
    
   
    
     nClipHight * nYClipNumIndex,
    
   
    
     nClipWidth,
    
   
    
     nClipHight);
    
   
    
    
   
    
     bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
     一. 底片效果
     
     原理: GetPixel方法获得每一点像素的值, 然后再使用SetPixel方法将取反后的颜色值设置到对应的点.
     
     效果图:
    
   
    
     
     
    
   
    
     代码实现:
    
   
    
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以底片效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap newbitmap = new Bitmap(Width, Height);
     
     Bitmap oldbitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel;
     
     for (int x = 1; x < Width; x++)
     
     {
     
     
     for (int y = 1; y < Height; y++)
     
     {
     
     
     int r, g, b;
     
     pixel = oldbitmap.GetPixel(x, y);
     
     r = 255 – pixel.R;
     
     g = 255 – pixel.G;
     
     b = 255 – pixel.B;
     
     newbitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
     
     }
     
     }
     
     this.pictureBox1.Image = newbitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”, MessageBoxButtons.OK, MessageBoxIcon.Information);
     
     }
     
     }
    
   
    
     二. 浮雕效果
    
   
    
     原理: 对图像像素点的像素值分别与相邻像素点的像素值相减后加上128, 然后将其作为新的像素点的值.
    
   
    
     效果图:
    
   
    
    
   
    
    
   
    
     
    
   
    
    
   
    
    
   
    
    
   
    
     代码实现:
    
   
    
     
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以浮雕效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap newBitmap = new Bitmap(Width, Height);
     
     Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel1, pixel2;
     
     for (int x = 0; x < Width – 1; x++)
     
     {
     
     
     for (int y = 0; y < Height – 1; y++)
     
     {
     
     
     int r = 0, g = 0, b = 0;
     
     pixel1 = oldBitmap.GetPixel(x, y);
     
     pixel2 = oldBitmap.GetPixel(x + 1, y + 1);
     
     r = Math.Abs(pixel1.R – pixel2.R + 128);
     
     g = Math.Abs(pixel1.G – pixel2.G + 128);
     
     b = Math.Abs(pixel1.B – pixel2.B + 128);
     
     if (r > 255)
     
     r = 255;
     
     if (r < 0)
     
     r = 0;
     
     if (g > 255)
     
     g = 255;
     
     if (g < 0)
     
     g = 0;
     
     if (b > 255)
     
     b = 255;
     
     if (b < 0)
     
     b = 0;
     
     newBitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
     
     }
     
     }
     
     this.pictureBox1.Image = newBitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”, MessageBoxButtons.OK, MessageBoxIcon.Information);
     
     }
     
     }
    
   
    
     三. 黑白效果
    
   
    
     原理: 彩色图像处理成黑白效果通常有3种算法;
    
   
    
     (1).最大值法: 使每个像素点的 R, G, B 值等于原像素点的 RGB (颜色值) 中最大的一个;
    
   
    
     (2).平均值法: 使用每个像素点的 R,G,B值等于原像素点的RGB值的平均值;
    
   
    
     (3).加权平均值法: 对每个像素点的 R, G, B值进行加权
    
   
    
     —自认为第三种方法做出来的黑白效果图像最 “真实”.
    
   
    
     效果图:
    
   
    
    
   
    
     
    
   
    
    
   
    
    
   
    
    
   
    
     代码实现:
    
   
    
     
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以黑白效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap newBitmap = new Bitmap(Width, Height);
     
     Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel;
     
     for (int x = 0; x < Width; x++)
     
     for (int y = 0; y < Height; y++)
     
     {
     
     
     pixel = oldBitmap.GetPixel(x, y);
     
     int r, g, b, Result = 0;
     
     r = pixel.R;
     
     g = pixel.G;
     
     b = pixel.B;
     
     //实例程序以加权平均值法产生黑白图像
     
     int iType =2;
     
     switch (iType)
     
     {
     
     
     case 0://平均值法
     
     Result = ((r + g + b) / 3);
     
     break;
     
     case 1://最大值法
     
     Result = r > g ? r : g;
     
     Result = Result > b ? Result : b;
     
     break;
     
     case 2://加权平均值法
     
     Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));
     
     break;
     
     }
     
     newBitmap.SetPixel(x, y, Color.FromArgb(Result, Result, Result));
     
     }
     
     this.pictureBox1.Image = newBitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”);
     
     }
     
     }
    
   
    
    
   
    
     四. 柔化效果
    
   
    
     原理: 当前像素点与周围像素点的颜色差距较大时取其平均值.
    
   
    
     效果图:
    
   
    
    
   
    
    
   
    
     
    
   
    
    
   
    
    
   
    
     代码实现:
    
   
    
     
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以柔化效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap bitmap = new Bitmap(Width, Height);
     
     Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel;
     
     //高斯模板
     
     int[] Gauss ={ 1, 2, 1, 2, 4, 2, 1, 2, 1 };
     
     for (int x = 1; x < Width – 1; x++)
     
     for (int y = 1; y < Height – 1; y++)
     
     {
     
     
     int r = 0, g = 0, b = 0;
     
     int Index = 0;
     
     for (int col = -1; col <= 1; col++)
     
     for (int row = -1; row <= 1; row++)
     
     {
     
     
     pixel = MyBitmap.GetPixel(x + row, y + col);
     
     r += pixel.R * Gauss[Index];
     
     g += pixel.G * Gauss[Index];
     
     b += pixel.B * Gauss[Index];
     
     Index++;
     
     }
     
     r /= 16;
     
     g /= 16;
     
     b /= 16;
     
     //处理颜色值溢出
     
     r = r > 255 ? 255 : r;
     
     r = r < 0 ? 0 : r;
     
     g = g > 255 ? 255 : g;
     
     g = g < 0 ? 0 : g;
     
     b = b > 255 ? 255 : b;
     
     b = b < 0 ? 0 : b;
     
     bitmap.SetPixel(x – 1, y – 1, Color.FromArgb(r, g, b));
     
     }
     
     this.pictureBox1.Image = bitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”);
     
     }
     
     }
    
   
    
     五.锐化效果
    
   
    
     原理:突出显示颜色值大(即形成形体边缘)的像素点.
    
   
    
     效果图:
    
   
    
    
   
    
     
    
   
    
    
   
    
    
   
    
    
   
    
     实现代码:
    
   
    
     
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以锐化效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap newBitmap = new Bitmap(Width, Height);
     
     Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel;
     
     //拉普拉斯模板
     
     int[] Laplacian ={ -1, -1, -1, -1, 9, -1, -1, -1, -1 };
     
     for (int x = 1; x < Width – 1; x++)
     
     for (int y = 1; y < Height – 1; y++)
     
     {
     
     
     int r = 0, g = 0, b = 0;
     
     int Index = 0;
     
     for (int col = -1; col <= 1; col++)
     
     for (int row = -1; row <= 1; row++)
     
     {
     
     
     pixel = oldBitmap.GetPixel(x + row, y + col); r += pixel.R * Laplacian[Index];
     
     g += pixel.G * Laplacian[Index];
     
     b += pixel.B * Laplacian[Index];
     
     Index++;
     
     }
     
     //处理颜色值溢出
     
     r = r > 255 ? 255 : r;
     
     r = r < 0 ? 0 : r;
     
     g = g > 255 ? 255 : g;
     
     g = g < 0 ? 0 : g;
     
     b = b > 255 ? 255 : b;
     
     b = b < 0 ? 0 : b;
     
     newBitmap.SetPixel(x – 1, y – 1, Color.FromArgb(r, g, b));
     
     }
     
     this.pictureBox1.Image = newBitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”);
     
     }
     
     }
    
   
    
     六. 雾化效果
    
   
    
     原理: 在图像中引入一定的随机值, 打乱图像中的像素值
    
   
    
     效果图:
    
   
    
    
   
    
     
    
   
    
    
   
    
     
    
   
    
     实现代码:
    
   
    
     
     private void button1_Click(object sender, EventArgs e)
     
     {
     
     
     //以雾化效果显示图像
     
     try
     
     {
     
     
     int Height = this.pictureBox1.Image.Height;
     
     int Width = this.pictureBox1.Image.Width;
     
     Bitmap newBitmap = new Bitmap(Width, Height);
     
     Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
     
     Color pixel;
     
     for (int x = 1; x < Width – 1; x++)
     
     for (int y = 1; y < Height – 1; y++)
     
     {
     
     
     System.Random MyRandom = new Random();
     
     int k = MyRandom.Next(123456);
     
     //像素块大小
     
     int dx = x + k % 19;
     
     int dy = y + k % 19;
     
     if (dx >= Width)
     
     dx = Width – 1;
     
     if (dy >= Height)
     
     dy = Height – 1;
     
     pixel = oldBitmap.GetPixel(dx, dy);
     
     newBitmap.SetPixel(x, y, pixel);
     
     }
     
     this.pictureBox1.Image = newBitmap;
     
     }
     
     catch (Exception ex)
     
     {
     
     
     MessageBox.Show(ex.Message, “信息提示”);
     
     }
     
     }
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
     
      
      
     
    
   
    
     
      
      
     
    
   
    
     
      
       浅谈
      
      
       Visual C#
      
      
       进行图像处理
      
     
    
   
    
    
   
    
     作者:彭军
     
      http://pengjun.org.cn
     
    
   
    
     这里之所以说“浅谈”是因为我这里只是简单的介绍如何使用Visual C#进行图像的读入、保存以及对像素的访问。而不涉及太多的算法。
    
   
    
     一、读入图像
    
   
    
     在Visual C#中我们可以使用一个Picture Box控件来显示图片,如下:
     
     private void btnOpenImage_Click(object sender, EventArgs e)
     
     {
     
     
     OpenFileDialog ofd = new OpenFileDialog();
     
     ofd.Filter = “BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*”;
     
     ofd.CheckFileExists = true;
     
     ofd.CheckPathExists = true;
     
     if (ofd.ShowDialog() == DialogResult.OK)
     
     {
     
     
     //pbxShowImage.ImageLocation = ofd.FileName;
     
     bmp = new Bitmap(ofd.FileName);
     
     if (bmp==null)
     
     {
     
     
     MessageBox.Show(“加载图片失败!”, “错误”);
     
     return;
     
     }
     
     pbxShowImage.Image = bmp;
     
     ofd.Dispose();
     
     }
     
     }
     
     其中bmp为类的一个对象:private Bitmap bmp=null;
     
     在使用Bitmap类和BitmapData类之前,需要使用using System.Drawing.Imaging;
     
     二、保存图像
     
     private void btnSaveImage_Click(object sender, EventArgs e)
     
     {
     
     
     if (bmp == null) return;
    
   
    
     SaveFileDialog sfd = new SaveFileDialog();
     
     sfd.Filter = “BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*”;
     
     if (sfd.ShowDialog() == DialogResult.OK)
     
     {
     
     
     pbxShowImage.Image.Save(sfd.FileName);
     
     MessageBox.Show(“保存成功!”,”提示”);
     
     sfd.Dispose();
     
     }
     
     }
     
     三、对像素的访问
     
     我们可以来建立一个GrayBitmapData类来做相关的处理。整个类的程序如下:
     
     using System;
     
     using System.Collections.Generic;
     
     using System.Linq;
     
     using System.Text;
     
     using System.Drawing;
     
     using System.Drawing.Imaging;
     
     using System.Windows.Forms;
    
   
    
     namespace ImageElf
     
     {
     
     
     class GrayBitmapData
     
     {
     
     
     public byte[,] Data;//保存像素矩阵
     
     public int Width;//图像的宽度
     
     public int Height;//图像的高度
    
   
    
     public GrayBitmapData()
     
     {
     
     
     this.Width = 0;
     
     this.Height = 0;
     
     this.Data = null;
     
     }
    
   
    
     public GrayBitmapData(Bitmap bmp)
     
     {
     
     
     BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
     
     this.Width = bmpData.Width;
     
     this.Height = bmpData.Height;
     
     Data = new byte[Height, Width];
     
     unsafe
     
     {
     
     
     byte* ptr = (byte*)bmpData.Scan0.ToPointer();
     
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     //将24位的RGB彩色图转换为灰度图
     
     int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));
     
     Data[i, j] = (byte)temp;
     
     }
     
     ptr += bmpData.Stride – Width * 3;//指针加上填充的空白空间
     
     }
     
     }
     
     bmp.UnlockBits(bmpData);
     
     }
    
   
    
     public GrayBitmapData(string path)
     
     : this(new Bitmap(path))
     
     {
     
     
     }
    
   
    
     public Bitmap ToBitmap()
     
     {
     
     
     Bitmap bmp=new Bitmap(Width,Height,PixelFormat.Format24bppRgb);
     
     BitmapData bmpData=bmp.LockBits(new Rectangle(0,0,Width,Height),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
     
     unsafe
     
     {
     
     
     byte* ptr=(byte*)bmpData.Scan0.ToPointer();
     
     for(int i=0;i<Height;i++)
     
     {
     
     
     for(int j=0;j<Width;j++)
     
     {
     
     
     *(ptr++)=Data[i,j];
     
     *(ptr++)=Data[i,j];
     
     *(ptr++)=Data[i,j];
     
     }
     
     ptr+=bmpData.Stride-Width*3;
     
     }
     
     }
     
     bmp.UnlockBits(bmpData);
     
     return bmp;
     
     }
    
   
    
     public void ShowImage(PictureBox pbx)
     
     {
     
     
     Bitmap b = this.ToBitmap();
     
     pbx.Image = b;
     
     //b.Dispose();
     
     }
    
   
    
     public void SaveImage(string path)
     
     {
     
     
     Bitmap b=ToBitmap();
     
     b.Save(path);
     
     //b.Dispose();
     
     }
     
     //均值滤波
     
     public void AverageFilter(int windowSize)
     
     {
     
     
     if (windowSize % 2 == 0)
     
     {
     
     
     return;
     
     }
    
   
    
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     int sum = 0;
     
     for (int g = -(windowSize – 1) / 2; g <= (windowSize – 1) / 2; g++)
     
     {
     
     
     for (int k = -(windowSize – 1) / 2; k <= (windowSize – 1) / 2; k++)
     
     {
     
     
     int a = i + g, b = j + k;
     
     if (a < 0) a = 0;
     
     if (a > Height – 1) a = Height – 1;
     
     if (b < 0) b = 0;
     
     if (b > Width – 1) b = Width – 1;
     
     sum += Data[a, b];
     
     }
     
     }
     
     Data[i,j]=(byte)(sum/(windowSize*windowSize));
     
     }
     
     }
     
     }
     
     //中值滤波
     
     public void MidFilter(int windowSize)
     
     {
     
     
     if (windowSize % 2 == 0)
     
     {
     
     
     return;
     
     }
    
   
    
     int[] temp = new int[windowSize * windowSize];
     
     byte[,] newdata = new byte[Height, Width];
     
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     int n = 0;
     
     for (int g = -(windowSize – 1) / 2; g <= (windowSize – 1) / 2; g++)
     
     {
     
     
     for (int k = -(windowSize – 1) / 2; k <= (windowSize – 1) / 2; k++)
     
     {
     
     
     int a = i + g, b = j + k;
     
     if (a < 0) a = 0;
     
     if (a > Height – 1) a = Height – 1;
     
     if (b < 0) b = 0;
     
     if (b > Width – 1) b = Width – 1;
     
     temp[n++]= Data[a, b];
     
     }
     
     }
     
     newdata[i, j] = GetMidValue(temp,windowSize*windowSize);
     
     }
     
     }
    
   
    
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     Data[i, j] = newdata[i, j];
     
     }
     
     }
     
     }
     
     //获得一个向量的中值
     
     private byte GetMidValue(int[] t, int length)
     
     {
     
     
     int temp = 0;
     
     for (int i = 0; i < length – 2; i++)
     
     {
     
     
     for (int j = i + 1; j < length – 1; j++)
     
     {
     
     
     if (t[i] > t[j])
     
     {
     
     
     temp = t[i];
     
     t[i] = t[j];
     
     t[j] = temp;
     
     }
     
     }
     
     }
    
   
    
     return (byte)t[(length – 1) / 2];
     
     }
     
     //一种新的滤波方法,是亮的更亮、暗的更暗
     
     public void NewFilter(int windowSize)
     
     {
     
     
     if (windowSize % 2 == 0)
     
     {
     
     
     return;
     
     }
    
   
    
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     int sum = 0;
     
     for (int g = -(windowSize – 1) / 2; g <= (windowSize – 1) / 2; g++)
     
     {
     
     
     for (int k = -(windowSize – 1) / 2; k <= (windowSize – 1) / 2; k++)
     
     {
     
     
     int a = i + g, b = j + k;
     
     if (a < 0) a = 0;
     
     if (a > Height – 1) a = Height – 1;
     
     if (b < 0) b = 0;
     
     if (b > Width – 1) b = Width – 1;
     
     sum += Data[a, b];
     
     }
     
     }
     
     double avg = (sum+0.0) / (windowSize * windowSize);
     
     if (avg / 255 < 0.5)
     
     {
     
     
     Data[i, j] = (byte)(2 * avg / 255 * Data[i, j]);
     
     }
     
     else
     
     {
     
     
     Data[i,j]=(byte)((1-2*(1-avg/255.0)*(1-Data[i,j]/255.0))*255);
     
     }
     
     }
     
     }
     
     }
     
     //直方图均衡
     
     public void HistEqual()
     
     {
     
     
     double[] num = new double[256] ;
     
     for(int i=0;i<256;i++) num[i]=0;
    
   
    
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     num[Data[i, j]]++;
     
     }
     
     }
    
   
    
     double[] newGray = new double[256];
     
     double n = 0;
     
     for (int i = 0; i < 256; i++)
     
     {
     
     
     n += num[i];
     
     newGray[i] = n * 255 / (Height * Width);
     
     }
    
   
    
     for (int i = 0; i < Height; i++)
     
     {
     
     
     for (int j = 0; j < Width; j++)
     
     {
     
     
     Data[i,j]=(byte)newGray[Data[i,j]];
     
     }
     
     }
     
     }
    
   
    
     }
     
     }
     
     在GrayBitmapData类中,只要我们对一个二维数组Data进行一系列的操作就是对图片的操作处理。在窗口上,我们可以使用
     
     一个按钮来做各种调用:
     
     //均值滤波
     
     private void btnAvgFilter_Click(object sender, EventArgs e)
     
     {
     
     
     if (bmp == null) return;
     
     GrayBitmapData gbmp = new GrayBitmapData(bmp);
     
     gbmp.AverageFilter(3);
     
     gbmp.ShowImage(pbxShowImage);
     
     }
     
     //转换为灰度图
     
     private void btnToGray_Click(object sender, EventArgs e)
     
     {
     
     
     if (bmp == null) return;
     
     GrayBitmapData gbmp = new GrayBitmapData(bmp);
     
     gbmp.ShowImage(pbxShowImage);
     
     }
    
   
    
    
   
    
     四、总结
    
   
    
     在Visual c#中对图像进行处理或访问,需要先建立一个Bitmap对象,然后通过其LockBits方法来获得一个BitmapData类的对象,然后通过获得其像素数据的首地址来对Bitmap对象的像素数据进行操作。当然,一种简单但是速度慢的方法是用Bitmap类的GetPixel和SetPixel方法。其中BitmapData类的Stride属性为每行像素所占的字节。
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
     
      
       C# colorMatrix
      
      对图片的处理 : 亮度调整 抓屏 翻转 随鼠标画矩形
     
    
   
    
     
     
    
   
    
     1.图片亮度处理
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      btn_Grap_Click
     
     (
     
      object
     
     
      sender
     
     ,
     
      EventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      //
     
     
      亮度百分比
     
    
   
    
     
      int
     
     
      percent
     
     = 50;
    
   
    
     
      Single
     
     
      v
     
     = 0.006F *
     
      percent
     
     ;
    
   
    
     
      Single
     
     [][]
     
      matrix
     
     = {
    
   
    
     
      new
     
     
      Single
     
     [] { 1, 0, 0, 0, 0 },
    
   
    
     
      new
     
     
      Single
     
     [] { 0, 1, 0, 0, 0 },
    
   
    
     
      new
     
     
      Single
     
     [] { 0, 0, 1, 0, 0 },
    
   
    
     
      new
     
     
      Single
     
     [] { 0, 0, 0, 1, 0 },
    
   
    
     
      new
     
     
      Single
     
     [] {
     
      v
     
     ,
     
      v
     
     ,
     
      v
     
     , 0, 1 }
    
   
    
     };
    
   
    
     
      System
     
     .
     
      Drawing
     
     .
     
      Imaging
     
     .
     
      ColorMatrix
     
     
      cm
     
     =
     
      new
     
     
      System
     
     .
     
      Drawing
     
     .
     
      Imaging
     
     .
     
      ColorMatrix
     
     (
     
      matrix
     
     );
    
   
    
     
      System
     
     .
     
      Drawing
     
     .
     
      Imaging
     
     .
     
      ImageAttributes
     
     
      attr
     
     =
     
      new
     
     
      System
     
     .
     
      Drawing
     
     .
     
      Imaging
     
     .
     
      ImageAttributes
     
     ();
    
   
    
     
      attr
     
     .
     
      SetColorMatrix
     
     (
     
      cm
     
     );
    
   
    
     
      //Image tmp
     
    
   
    
     
      Image
     
     
      tmp
     
     =
     
      Image
     
     .
     
      FromFile
     
     (
     
      “1.png”
     
     );
    
   
    
    
   
    
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      Image
     
     =
     
      Image
     
     .
     
      FromFile
     
     (
     
      “1.png”
     
     );
    
   
    
    
   
    
     
      Graphics
     
     
      g
     
     =
     
      Graphics
     
     .
     
      FromImage
     
     (
     
      tmp
     
     );
    
   
    
     
      try
     
    
   
    
     {
     
    
   
    
     
      Rectangle
     
     
      destRect
     
     =
     
      new
     
     
      Rectangle
     
     (0, 0,
     
      tmp
     
     .
     
      Width
     
     ,
     
      tmp
     
     .
     
      Height
     
     );
    
   
    
     
      g
     
     .
     
      DrawImage
     
     (
     
      tmp
     
     ,
     
      destRect
     
     , 0, 0,
     
      tmp
     
     .
     
      Width
     
     ,
     
      tmp
     
     .
     
      Height
     
     ,
     
      GraphicsUnit
     
     .
     
      Pixel
     
     ,
     
      attr
     
     );
    
   
    
     }
    
   
    
     
      finally
     
    
   
    
     {
    
   
    
     
      g
     
     .
     
      Dispose
     
     ();
    
   
    
     }
    
   
    
    
   
    
     
      this
     
     .
     
      pictureBox_Dest
     
     .
     
      Image
     
     = (
     
      Image
     
     )
     
      tmp
     
     .
     
      Clone
     
     ();
    
   
    
     }
    
   
    
     
     
    
   
    
     
     
    
   
    
     2.抓屏将生成的图片显示在pictureBox
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      btn_Screen_Click
     
     (
     
      object
     
     
      sender
     
     ,
     
      EventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      Image
     
     
      myImage
     
     =
     
      new
     
     
      Bitmap
     
     (
     
      Screen
     
     .
     
      PrimaryScreen
     
     .
     
      Bounds
     
     .
     
      Width
     
     ,
     
      Screen
     
     .
     
      PrimaryScreen
     
     .
     
      Bounds
     
     .
     
      Height
     
     );
    
   
    
     
      Graphics
     
     
      g
     
     =
     
      Graphics
     
     .
     
      FromImage
     
     (
     
      myImage
     
     );
    
   
    
     
      g
     
     .
     
      CopyFromScreen
     
     (
     
      new
     
     
      Point
     
     (0, 0),
     
      new
     
     
      Point
     
     (0, 0),
     
      new
     
     
      Size
     
     (
     
      Screen
     
     .
     
      PrimaryScreen
     
     .
     
      Bounds
     
     .
     
      Width
     
     ,
     
      Screen
     
     .
     
      PrimaryScreen
     
     .
     
      Bounds
     
     .
     
      Height
     
     ));
    
   
    
     //
     
      IntPtr
     
     
      dc1
     
     =
     
      g
     
     .
     
      GetHdc
     
     ();
     
      //此处这两句多余,具体看最后GetHdc()定义
     
    
   
    
     //
     
      g
     
     .
     
      ReleaseHdc
     
     (
     
      dc1
     
     );
    
   
    
     
      g
     
     .
     
      Dispose
     
     ();
    
   
    
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      SizeMode
     
     =
     
      PictureBoxSizeMode
     
     .
     
      StretchImage
     
     ;
    
   
    
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      Image
     
     =
     
      myImage
     
     ;
    
   
    
     
      myImage
     
     .
     
      Save
     
     (
     
      “Screen”
     
     ,
     
      ImageFormat
     
     .
     
      Png
     
     );
    
   
    
     }
    
   
    
    
   
    
     3.翻转
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      btn_RotateFlip_Click
     
     (
     
      object
     
     
      sender
     
     ,
     
      EventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      Image
     
     =
     
      Image
     
     .
     
      FromFile
     
     (
     
      “1.png”
     
     );
    
   
    
    
   
    
     
      Image
     
     
      tmp
     
     =
     
      Image
     
     .
     
      FromFile
     
     (
     
      “1.png”
     
     );
    
   
    
    
   
    
     
      tmp
     
     .
     
      RotateFlip
     
     (
     
      RotateFlipType
     
     .
     
      Rotate90FlipNone
     
     );
    
   
    
     
      this
     
     .
     
      pictureBox_Dest
     
     .
     
      Image
     
     =
     
      tmp
     
     ;
    
   
    
     }
    
   
    
     4.跟随鼠标在 pictureBox的图片上画矩形
    
   
    
     
      private
     
     
      int
     
     
      intStartX
     
     = 0;
    
   
    
     
      private
     
     
      int
     
     
      intStartY
     
     = 0;
    
   
    
     
      private
     
     
      bool
     
     
      isMouseDraw
     
     =
     
      false
     
     ;
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      pictureBox_Src_MouseDown
     
     (
     
      object
     
     
      sender
     
     ,
     
      MouseEventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      isMouseDraw
     
     =
     
      true
     
     ;
    
   
    
    
   
    
     
      intStartX
     
     =
     
      e
     
     .
     
      X
     
     ;
    
   
    
     
      intStartY
     
     =
     
      e
     
     .
     
      Y
     
     ;
    
   
    
     }
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      pictureBox_Src_MouseMove
     
     (
     
      object
     
     
      sender
     
     ,
     
      MouseEventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      if
     
     (
     
      isMouseDraw
     
     )
    
   
    
     {
     
    
   
    
     
      try
     
    
   
    
     {
     
    
   
    
     
      //Image tmp = Image.FromFile(“1.png”);
     
    
   
    
     
      Graphics
     
     
      g
     
     =
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      CreateGraphics
     
     ();
    
   
    
     
      //
     
     
      清空上次画下的痕迹
     
    
   
    
     
      g
     
     .
     
      Clear
     
     (
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      BackColor
     
     );
    
   
    
     
      Brush
     
     
      brush
     
     =
     
      new
     
     
      SolidBrush
     
     (
     
      Color
     
     .
     
      Red
     
     );
    
   
    
     
      Pen
     
     
      pen
     
     =
     
      new
     
     
      Pen
     
     (
     
      brush
     
     , 1);
    
   
    
     
      pen
     
     .
     
      DashStyle
     
     =
     
      DashStyle
     
     .
     
      Solid
     
     ;
    
   
    
     
      g
     
     .
     
      DrawRectangle
     
     (
     
      pen
     
     ,
     
      new
     
     
      Rectangle
     
     (
     
      intStartX
     
     >
     
      e
     
     .
     
      X
     
     ?
     
      e
     
     .
     
      X
     
     :
     
      intStartX
     
     ,
     
      intStartY
     
     >
     
      e
     
     .
     
      Y
     
     ?
     
      e
     
     .
     
      Y
     
     :
     
      intStartY
     
     ,
     
      Math
     
     .
     
      Abs
     
     (
     
      e
     
     .
     
      X
     
     –
     
      intStartX
     
     ),
     
      Math
     
     .
     
      Abs
     
     (
     
      e
     
     .
     
      Y
     
     –
     
      intStartY
     
     )));
    
   
    
     
      g
     
     .
     
      Dispose
     
     ();
    
   
    
     
      //this.pictureBox_Src.Image = tmp;
     
    
   
    
     }
    
   
    
     
      catch
     
     (
     
      Exception
     
     
      ex
     
     )
    
   
    
     {
     
    
   
    
     
      ex
     
     .
     
      ToString
     
     ();
    
   
    
     }
    
   
    
     }
    
   
    
     }
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      pictureBox_Src_MouseUp
     
     (
     
      object
     
     
      sender
     
     ,
     
      MouseEventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      isMouseDraw
     
     =
     
      false
     
     ;
    
   
    
    
   
    
     
      intStartX
     
     = 0;
    
   
    
     
      intStartY
     
     = 0;
    
   
    
     }
    
   
    
     5.取灰度
    
   
    
    
   
    
     
      private
     
     
      void
     
     
      btn_GetGray_Click
     
     (
     
      object
     
     
      sender
     
     ,
     
      EventArgs
     
     
      e
     
     )
    
   
    
     {
     
    
   
    
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      Image
     
     =
     
      Image
     
     .
     
      FromFile
     
     (
     
      “1.png”
     
     );
    
   
    
     
      Bitmap
     
     
      currentBitmap
     
     =
     
      new
     
     
      Bitmap
     
     (
     
      this
     
     .
     
      pictureBox_Src
     
     .
     
      Image
     
     );
    
   
    
     
      Graphics
     
     
      g
     
     =
     
      Graphics
     
     .
     
      FromImage
     
     (
     
      currentBitmap
     
     );
    
   
    
     
      ImageAttributes
     
     
      ia
     
     =
     
      new
     
     
      ImageAttributes
     
     ();
    
   
    
     
      float
     
     [][]
     
      colorMatrix
     
     =   {
    
   
    
     
      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
     
     
      cm
     
     =
     
      new
     
     
      ColorMatrix
     
     (
     
      colorMatrix
     
     );
    
   
    
     
      ia
     
     .
     
      SetColorMatrix
     
     (
     
      cm
     
     ,
     
      ColorMatrixFlag
     
     .
     
      Default
     
     ,
     
      ColorAdjustType
     
     .
     
      Bitmap
     
     );
    
   
    
     
      g
     
     .
     
      DrawImage
     
     (
     
      currentBitmap
     
     ,
     
      new
     
     
      Rectangle
     
     (0, 0,
     
      currentBitmap
     
     .
     
      Width
     
     ,
     
      currentBitmap
     
     .
     
      Height
     
     ), 0, 0,
     
      currentBitmap
     
     .
     
      Width
     
     ,
     
      currentBitmap
     
     .
     
      Height
     
     ,
     
      GraphicsUnit
     
     .
     
      Pixel
     
     ,
     
      ia
     
     );
    
   
    
     
      this
     
     .
     
      pictureBox_Dest
     
     .
     
      Image
     
     = (
     
      Image
     
     )(
     
      currentBitmap
     
     .
     
      Clone
     
     ());
    
   
    
     
      g
     
     .
     
      Dispose
     
     ();
    
   
    
     }
    
   
    
    
   
    
    
   
    
    
   
    
    
   
    
     
      Graphics.GetHdc 方法
     
    
   
    
     
      .NET Framework 4
     
    
   
    
     获取与此
     
      Graphics
     
     关联的设备上下文的句柄。
    
   
    
     
      命名空间:
     
     
      System.Drawing
     
     
     
      程序集:
     
     System.Drawing(在 System.Drawing.dll 中)
    
   
    
     [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags =
    
   
    
     SecurityPermissionFlag.UnmanagedCode)]
    
   
    
     public IntPtr GetHdc()
    
   
    
     
      返回值
     
    
   
    
     类型:
     
      System.IntPtr
     
     
     与此
     
      Graphics
     
     关联的设备上下文的句柄。
    
   
    
     
      实现
     
    
   
    
     设备上下文是一个基于 GDI 的 Windows 结构,它定义一组图形对象及其关联的特性,以及影响输出的图形模式。 此方法返回该设备上下文(字体除外)。由于未选择字体,使用 GetHdc 方法返回的句柄对
     
      FromHdc
     
     方法进行调用将会失败。
    
   
    
     GetHdc 方法调用和
     
      ReleaseHdc
     
     方法调用必须成对出现。 在 GetHdc 和
     
      ReleaseHdc
     
     方法对的范围内,通常仅调用 GDI 函数。 在该范围内对
     
      Graphics
     
     (它产生
     
      hdc
     
     参数)的 GDI+ 方法的调用因 ObjectBusy 错误而失败。 此外,GDI+ 忽略后续操作中对
     
      hdc
     
     参数的
     
      Graphics
     
     所做的所有状态更改。
    
   
    
     下面的代码示例设计为与 Windows 窗体一起使用,它需要
     
      PaintEventArgs
     
     
      e
     
     ,即
     
      Paint
     
     事件处理程序的一个参数。 该示例演示如何调用 Windows GDI 函数以执行与 GDI+
     
      Graphics
     
     方法相同的任务。 代码执行下列操作:
    
   
- 
     
 为 Windows DLL 文件 gdi32.dll 定义互操作性
 
 DllImportAttribute
 
 特性。 此 DLL 包含所需的 GDI 函数。
 
- 
     
 将该 DLL 中的
 
 Rectangle
 
 函数定义为外部函数。
 
- 
     
 创建一支红色钢笔。
 
- 
     
 利用该钢笔,使用 GDI+
 
 DrawRectangle
 
 方法将矩形绘制到屏幕。
 
- 
     
 定义内部指针类型变量
 
 hdc
 
 并将它的值设置为窗体的设备上下文句柄。
 
- 
     
 使用 GDI
 
 Rectangle
 
 函数将矩形绘制到屏幕。
 
    
     释放由
     
      hdc
     
     参数表示的设备上下文。
    
   
    
    
   
    
     public class GDI
    
   
    
     {
     
    
   
    
     [System.Runtime.InteropServices.DllImport(“gdi32.dll”)]
    
   
    
     internal static extern bool Rectangle(
    
   
    
     IntPtr hdc,
    
   
    
     int ulCornerX, int ulCornerY,
    
   
    
     int lrCornerX, int lrCornerY);
    
   
    
     }
    
   
    
    
   
    
     [System.Security.Permissions.SecurityPermission(
    
   
    
     System.Security.Permissions.SecurityAction.LinkDemand, Flags =
    
   
    
     System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]
    
   
    
     private void GetHdcForGDI1(PaintEventArgs e)
    
   
    
     {
     
    
   
    
     // Create pen.
    
   
    
     Pen redPen = new Pen(Color.Red, 1);
    
   
    
    
   
    
     // Draw rectangle with GDI+.
    
   
    
     e.Graphics.DrawRectangle(redPen, 10, 10, 100, 50);
    
   
    
    
   
    
     // Get handle to device context.
    
   
    
     IntPtr hdc = e.Graphics.GetHdc();
    
   
    
    
   
    
     // Draw rectangle with GDI using default pen.
    
   
    
     GDI.Rectangle(hdc, 10, 70, 110, 120);
    
   
    
    
   
    
     // Release handle to device context.
    
   
    
     e.Graphics.ReleaseHdc(hdc);
    
   
    
     }
    
   
    
    
   
    
    
   
    
    
   
    
    
   
 
