C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

C#图像处理(各种旋转、改变大小、柔化、锐化、雾化、底片、浮雕、黑白、滤镜效果)

标签: c#图像处理gdi
本文章已收录于:
分类:

一、各种旋转、改变大小

注意:先要添加画图相关的using引用。

[csharp] view plain copy
 
print?
  1. //向右旋转图像90°代码如下:  
  2. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  3. {  
  4. Graphics g = e.Graphics;  
  5. Bitmap bmp = new Bitmap("rama.jpg");//加载图像  
  6. g.FillRectangle(Brushes.White, this.ClientRectangle);//填充窗体背景为白色  
  7. Point[] destinationPoints = {  
  8. new Point(100, 0), // destination for upper-left point of original  
  9. new Point(100, 100),// destination for upper-right point of original  
  10. new Point(0, 0)}; // destination for lower-left point of original  
  11. g.DrawImage(bmp, destinationPoints);  
  12. }  
  13.   
  14. //旋转图像180°代码如下:  
  15. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  16. {  
  17. Graphics g = e.Graphics;  
  18. Bitmap bmp = new Bitmap("rama.jpg");  
  19. g.FillRectangle(Brushes.White, this.ClientRectangle);  
  20. Point[] destinationPoints = {  
  21. new Point(0, 100), // destination for upper-left point of original  
  22. new Point(100, 100),// destination for upper-right point of original  
  23. new Point(0, 0)}; // destination for lower-left point of original  
  24. g.DrawImage(bmp, destinationPoints);  
  25. }  
  26.   
  27. //图像切变代码:  
  28. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  29. {  
  30. Graphics g = e.Graphics;  
  31. Bitmap bmp = new Bitmap("rama.jpg");  
  32. g.FillRectangle(Brushes.White, this.ClientRectangle);  
  33. Point[] destinationPoints = {  
  34. new Point(0, 0), // destination for upper-left point of original  
  35. new Point(100, 0), // destination for upper-right point of original  
  36. new Point(50, 100)};// destination for lower-left point of original  
  37. g.DrawImage(bmp, destinationPoints);  
  38. }  
  39.   
  40. //图像截取:  
  41. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  42. {  
  43. Graphics g = e.Graphics;  
  44. Bitmap bmp = new Bitmap("rama.jpg");  
  45. g.FillRectangle(Brushes.White, this.ClientRectangle);  
  46. Rectangle sr = new Rectangle(80, 60, 400, 400);//要截取的矩形区域  
  47. Rectangle dr = new Rectangle(0, 0, 200, 200);//要显示到Form的矩形区域  
  48. g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);  
  49. }  
  50.   
  51. //改变图像大小:  
  52. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  53. {  
  54. Graphics g = e.Graphics;  
  55. Bitmap bmp = new Bitmap("rama.jpg");  
  56. g.FillRectangle(Brushes.White, this.ClientRectangle);  
  57. int width = bmp.Width;  
  58. int height = bmp.Height;  
  59. // 改变图像大小使用低质量的模式  
  60. g.InterpolationMode = InterpolationMode.NearestNeighbor;  
  61. g.DrawImage(bmp, new Rectangle(10, 10, 120, 120), // source rectangle  
  62. new Rectangle(0, 0, width, height), // destination rectangle  
  63. GraphicsUnit.Pixel);  
  64. // 使用高质量模式  
  65. //g.CompositingQuality = CompositingQuality.HighSpeed;  
  66. g.InterpolationMode = InterpolationMode.HighQualityBicubic;  
  67. g.DrawImage(  
  68. bmp,  
  69. new Rectangle(130, 10, 120, 120),   
  70. new Rectangle(0, 0, width, height),  
  71. GraphicsUnit.Pixel);  
  72. }  
  73.   
  74. //设置图像的分辩率:  
  75. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  76. {  
  77. Graphics g = e.Graphics;  
  78. Bitmap bmp = new Bitmap("rama.jpg");  
  79. g.FillRectangle(Brushes.White, this.ClientRectangle);  
  80. bmp.SetResolution(300f, 300f);  
  81. g.DrawImage(bmp, 0, 0);  
  82. bmp.SetResolution(1200f, 1200f);  
  83. g.DrawImage(bmp, 180, 0);  
  84. }  
  85.   
  86. //用GDI+画图  
  87. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  88. {  
  89. Graphics gForm = e.Graphics;  
  90. gForm.FillRectangle(Brushes.White, this.ClientRectangle);  
  91. for (int i = 1; i <= 7; ++i)  
  92. {  
  93. //在窗体上面画出橙色的矩形  
  94. Rectangle r = new Rectangle(i*40-15, 0, 15,  
  95. this.ClientRectangle.Height);  
  96. gForm.FillRectangle(Brushes.Orange, r);  
  97. }  
  98. //在内存中创建一个Bitmap并设置CompositingMode  
  99. Bitmap bmp = new Bitmap(260, 260,  
  100. System.Drawing.Imaging.PixelFormat.Format32bppArgb);  
  101. Graphics gBmp = Graphics.FromImage(bmp);  
  102. gBmp.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;  
  103. // 创建一个带有Alpha的红色区域  
  104. // 并将其画在内存的位图里面  
  105. Color red = Color.FromArgb(0x60, 0xff, 0, 0);  
  106. Brush redBrush = new SolidBrush(red);  
  107. gBmp.FillEllipse(redBrush, 70, 70, 160, 160);  
  108. // 创建一个带有Alpha的绿色区域  
  109. Color green = Color.FromArgb(0x40, 0, 0xff, 0);  
  110. Brush greenBrush = new SolidBrush(green);  
  111. gBmp.FillRectangle(greenBrush, 10, 10, 140, 140);  
  112. //在窗体上面画出位图 now draw the bitmap on our window  
  113. gForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height);  
  114. // 清理资源  
  115. bmp.Dispose();  
  116. gBmp.Dispose();  
  117. redBrush.Dispose();  
  118. greenBrush.Dispose();  
  119. }  
  120.   
  121. //在窗体上面绘图并显示图像  
  122. private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)  
  123. {  
  124. Graphics g = e.Graphics;  
  125. Pen blackPen = new Pen(Color.Black, 1);  
  126. if (ClientRectangle.Height / 10 > 0)  
  127. {  
  128. for (int y = 0; y < ClientRectangle.Height; y += ClientRectangle.Height / 10)  
  129. {  
  130. g.DrawLine(blackPen, new Point(0, 0), new Point(ClientRectangle.Width, y));  
  131. }  
  132. }  
  133. blackPen.Dispose();  
  134. }  
//向右旋转图像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事件中加入下面的代码即可。

[csharp] view plain copy
 
print?
  1. //导入图像资源  
  2.             Bitmap bmpRes = null;  
  3.             String strPath = Application.ExecutablePath;  
  4.             try{  
  5.                 int nEndIndex = strPath.LastIndexOf('//');  
  6.                 strPath = strPath.Substring(0,nEndIndex) + "//Bmp//BmpResMM.bmp";  
  7.                 bmpRes = new Bitmap(strPath);  
  8.    
  9.                 //窗体上显示加载图片  
  10.                 pictureBoxBmpRes.Width = bmpRes.Width;  
  11.                 pictureBoxBmpRes.Height = bmpRes.Height;  
  12.                 pictureBoxBmpRes.Image = bmpRes;  
  13.             }  
  14.             catch(Exception ex)  
  15.             {  
  16.                System.Windows.Forms.MessageBox.Show("图片资源加载失败!/r/n" + ex.ToString());  
  17.             }  
  18.    
  19.             //裁剪图片(裁成2行3列的6张图片)  
  20.             int nYClipNum = 2, nXClipNum = 3;  
  21.             Bitmap[] bmpaClipBmpArr = new Bitmap[nYClipNum * nXClipNum];              
  22.             for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)  
  23.             {  
  24.                 for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)  
  25.                 {  
  26.                     int nClipWidth = bmpRes.Width / nXClipNum;  
  27.                     int nClipHight = bmpRes.Height / nYClipNum;  
  28.                     int nBmpIndex = nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0?1:0);  
  29.                     bmpaClipBmpArr[nBmpIndex] = new Bitmap(nClipWidth, nClipHight);  
  30.    
  31.                     for(int nY = 0; nY < nClipHight; nY++)  
  32.                     {  
  33.                         for(int nX = 0; nX < nClipWidth; nX++)  
  34.                         {  
  35.                             int nClipX = nX + nClipWidth * nXClipNumIndex;  
  36.                             int nClipY = nY + nClipHight * nYClipNumIndex;  
  37.                             Color cClipPixel = bmpRes.GetPixel(nClipX, nClipY);  
  38.                             bmpaClipBmpArr[nBmpIndex].SetPixel(nX, nY, cClipPixel);  
  39.                         }  
  40.                     }                     
  41.                 }  
  42.             }  
  43.             PictureBox[] picbShow = new PictureBox[nYClipNum * nXClipNum];  
  44.             picbShow[0] = pictureBox1;  
  45.             picbShow[1] = pictureBox2;  
  46.             picbShow[2] = pictureBox3;  
  47.             picbShow[3] = pictureBox4;  
  48.             picbShow[4] = pictureBox5;  
  49.             picbShow[5] = pictureBox6;  
  50.             for (int nLoop = 0; nLoop < nYClipNum * nXClipNum; nLoop++)  
  51.             {  
  52.                 picbShow[nLoop].Width = bmpRes.Width / nXClipNum;  
  53.                 picbShow[nLoop].Height = bmpRes.Height / nYClipNum;  
  54.                 picbShow[nLoop].Image = bmpaClipBmpArr[nLoop];                 
  55.             }  
//导入图像资源
            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)。第一个方法将创建并返回一个精确的实例对象,后两个就是我们这里需要用的局部裁剪了(其实后两个方法本人觉得用法上差不多)。

将上面的程序稍稍改进下——将裁剪的处理放到一个按钮事件函数中,然后再托一个按钮好窗体上,最后将下面的代码复制到该按钮的事件函数中。

[csharp] view plain copy
 
print?
  1. for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)  
  2. {  
  3.        for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)  
  4.          {  
  5.               int nClipWidth = bmpRes.Width / nXClipNum;  
  6.                       int nClipHight = bmpRes.Height / nYClipNum;  
  7.                 int nBmpIndex =  
  8. nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0 ? 1 : 0);  
  9.                
  10.         Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,  
  11.                                                             nClipHight * nYClipNumIndex,  
  12.                                                             nClipWidth,  
  13.                                                             nClipHight);  
  14.                
  15.                 bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);  
  16.             }  
  17. }  
  18.    
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循环中的拷贝部分的处理,

[csharp] view plain copy
 
print?
  1. Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,  
  2.                                                             nClipHight * nYClipNumIndex,  
  3.                                                             nClipWidth,  
  4.                                                             nClipHight);  
  5.    
  6. bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);  
  7.    
Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,
                                                            nClipHight * nYClipNumIndex,
                                                            nClipWidth,
                                                            nClipHight);
 
bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);
 

 

一. 底片效果
原理: GetPixel方法获得每一点像素的值, 然后再使用SetPixel方法将取反后的颜色值设置到对应的点.
效果图:

代码实现:

 

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.      {  
  3.          //以底片效果显示图像  
  4.          try  
  5.          {  
  6.              int Height = this.pictureBox1.Image.Height;  
  7.              int Width = this.pictureBox1.Image.Width;  
  8.              Bitmap newbitmap = new Bitmap(Width, Height);  
  9.              Bitmap oldbitmap = (Bitmap)this.pictureBox1.Image;  
  10.              Color pixel;  
  11.              for (int x = 1; x < Width; x++)  
  12.              {  
  13.                  for (int y = 1; y < Height; y++)  
  14.                  {  
  15.                      int r, g, b;  
  16.                      pixel = oldbitmap.GetPixel(x, y);  
  17.                      r = 255 - pixel.R;  
  18.                      g = 255 - pixel.G;  
  19.                      b = 255 - pixel.B;  
  20.                      newbitmap.SetPixel(x, y, Color.FromArgb(r, g, b));  
  21.                  }  
  22.              }  
  23.              this.pictureBox1.Image = newbitmap;  
  24.          }  
  25.          catch (Exception ex)  
  26.          {  
  27.              MessageBox.Show(ex.Message, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
  28.          }  
  29.      }  
   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, 然后将其作为新的像素点的值.

效果图:

 

 

 

 

 

代码实现:

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.         {  
  3.             //以浮雕效果显示图像  
  4.             try  
  5.             {  
  6.                 int Height = this.pictureBox1.Image.Height;  
  7.                 int Width = this.pictureBox1.Image.Width;  
  8.                 Bitmap newBitmap = new Bitmap(Width, Height);  
  9.                 Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;  
  10.                 Color pixel1, pixel2;  
  11.                 for (int x = 0; x < Width - 1; x++)  
  12.                 {  
  13.                     for (int y = 0; y < Height - 1; y++)  
  14.                     {  
  15.                         int r = 0, g = 0, b = 0;  
  16.                         pixel1 = oldBitmap.GetPixel(x, y);  
  17.                         pixel2 = oldBitmap.GetPixel(x + 1, y + 1);  
  18.                         r = Math.Abs(pixel1.R - pixel2.R + 128);  
  19.                         g = Math.Abs(pixel1.G - pixel2.G + 128);  
  20.                         b = Math.Abs(pixel1.B - pixel2.B + 128);  
  21.                         if (r > 255)  
  22.                             r = 255;  
  23.                         if (r < 0)  
  24.                             r = 0;  
  25.                         if (g > 255)  
  26.                             g = 255;  
  27.                         if (g < 0)  
  28.                             g = 0;  
  29.                         if (b > 255)  
  30.                             b = 255;  
  31.                         if (b < 0)  
  32.                             b = 0;  
  33.                         newBitmap.SetPixel(x, y, Color.FromArgb(r, g, b));  
  34.                     }  
  35.                 }  
  36.                 this.pictureBox1.Image = newBitmap;  
  37.             }  
  38.             catch (Exception ex)  
  39.             {  
  40.                 MessageBox.Show(ex.Message, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
  41.             }  
  42.         }  
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值进行加权

      ---自认为第三种方法做出来的黑白效果图像最 "真实".

效果图:

 

 

代码实现:

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.         {  
  3.             //以黑白效果显示图像  
  4.             try  
  5.             {  
  6.                 int Height = this.pictureBox1.Image.Height;  
  7.                 int Width = this.pictureBox1.Image.Width;  
  8.                 Bitmap newBitmap = new Bitmap(Width, Height);  
  9.                 Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;  
  10.                 Color pixel;  
  11.                 for (int x = 0; x < Width; x++)  
  12.                     for (int y = 0; y < Height; y++)  
  13.                     {  
  14.                         pixel = oldBitmap.GetPixel(x, y);  
  15.                         int r, g, b, Result = 0;  
  16.                         r = pixel.R;  
  17.                         g = pixel.G;  
  18.                         b = pixel.B;  
  19.                         //实例程序以加权平均值法产生黑白图像  
  20.                         int iType =2;  
  21.                         switch (iType)  
  22.                         {  
  23.                             case 0://平均值法  
  24.                                 Result = ((r + g + b) / 3);  
  25.                                 break;  
  26.                             case 1://最大值法  
  27.                                 Result = r > g ? r : g;  
  28.                                 Result = Result > b ? Result : b;  
  29.                                 break;  
  30.                             case 2://加权平均值法  
  31.                                 Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));  
  32.                                 break;  
  33.                         }  
  34.                         newBitmap.SetPixel(x, y, Color.FromArgb(Result, Result, Result));  
  35.                     }  
  36.                 this.pictureBox1.Image = newBitmap;  
  37.             }  
  38.             catch (Exception ex)  
  39.             {  
  40.                 MessageBox.Show(ex.Message, "信息提示");  
  41.             }  
  42.         }  
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, "信息提示");
            }
        }

 

四. 柔化效果

原理: 当前像素点与周围像素点的颜色差距较大时取其平均值.

效果图:

 

 

 

 

代码实现:

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.        {  
  3.            //以柔化效果显示图像  
  4.            try  
  5.            {  
  6.                int Height = this.pictureBox1.Image.Height;  
  7.                int Width = this.pictureBox1.Image.Width;  
  8.                Bitmap bitmap = new Bitmap(Width, Height);  
  9.                Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;  
  10.                Color pixel;  
  11.                //高斯模板  
  12.                int[] Gauss ={ 1, 2, 1, 2, 4, 2, 1, 2, 1 };  
  13.                for (int x = 1; x < Width - 1; x++)  
  14.                    for (int y = 1; y < Height - 1; y++)  
  15.                    {  
  16.                        int r = 0, g = 0, b = 0;  
  17.                        int Index = 0;  
  18.                        for (int col = -1; col <= 1; col++)  
  19.                            for (int row = -1; row <= 1; row++)  
  20.                            {  
  21.                                pixel = MyBitmap.GetPixel(x + row, y + col);  
  22.                                r += pixel.R * Gauss[Index];  
  23.                                g += pixel.G * Gauss[Index];  
  24.                                b += pixel.B * Gauss[Index];  
  25.                                Index++;  
  26.                            }  
  27.                        r /= 16;  
  28.                        g /= 16;  
  29.                        b /= 16;  
  30.                        //处理颜色值溢出  
  31.                        r = r > 255 ? 255 : r;  
  32.                        r = r < 0 ? 0 : r;  
  33.                        g = g > 255 ? 255 : g;  
  34.                        g = g < 0 ? 0 : g;  
  35.                        b = b > 255 ? 255 : b;  
  36.                        b = b < 0 ? 0 : b;  
  37.                        bitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b));  
  38.                    }  
  39.                this.pictureBox1.Image = bitmap;  
  40.            }  
  41.            catch (Exception ex)  
  42.            {  
  43.                MessageBox.Show(ex.Message, "信息提示");  
  44.            }  
  45.        }  
 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, "信息提示");
            }
        }


五.锐化效果

原理:突出显示颜色值大(即形成形体边缘)的像素点.

效果图:

 

 

 

 

实现代码:

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.       {  
  3.           //以锐化效果显示图像  
  4.           try  
  5.           {  
  6.               int Height = this.pictureBox1.Image.Height;  
  7.               int Width = this.pictureBox1.Image.Width;  
  8.               Bitmap newBitmap = new Bitmap(Width, Height);  
  9.               Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;  
  10.               Color pixel;  
  11.               //拉普拉斯模板  
  12.               int[] Laplacian ={ -1, -1, -1, -1, 9, -1, -1, -1, -1 };  
  13.               for (int x = 1; x < Width - 1; x++)  
  14.                   for (int y = 1; y < Height - 1; y++)  
  15.                   {  
  16.                       int r = 0, g = 0, b = 0;  
  17.                       int Index = 0;  
  18.                       for (int col = -1; col <= 1; col++)  
  19.                           for (int row = -1; row <= 1; row++)  
  20.                           {  
  21.                               pixel = oldBitmap.GetPixel(x + row, y + col); r += pixel.R * Laplacian[Index];  
  22.                               g += pixel.G * Laplacian[Index];  
  23.                               b += pixel.B * Laplacian[Index];  
  24.                               Index++;  
  25.                           }  
  26.                       //处理颜色值溢出  
  27.                       r = r > 255 ? 255 : r;  
  28.                       r = r < 0 ? 0 : r;  
  29.                       g = g > 255 ? 255 : g;  
  30.                       g = g < 0 ? 0 : g;  
  31.                       b = b > 255 ? 255 : b;  
  32.                       b = b < 0 ? 0 : b;  
  33.                       newBitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b));  
  34.                   }  
  35.               this.pictureBox1.Image = newBitmap;  
  36.           }  
  37.           catch (Exception ex)  
  38.           {  
  39.               MessageBox.Show(ex.Message, "信息提示");  
  40.           }  
  41.       }  
  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, "信息提示");
            }
        }

 

六. 雾化效果

原理: 在图像中引入一定的随机值, 打乱图像中的像素值

效果图:

 

 

 

实现代码:

[csharp] view plain copy
 
print?
  1. private void button1_Click(object sender, EventArgs e)  
  2.  {  
  3.      //以雾化效果显示图像  
  4.      try  
  5.      {  
  6.          int Height = this.pictureBox1.Image.Height;  
  7.          int Width = this.pictureBox1.Image.Width;  
  8.          Bitmap newBitmap = new Bitmap(Width, Height);  
  9.          Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;  
  10.          Color pixel;  
  11.          for (int x = 1; x < Width - 1; x++)  
  12.              for (int y = 1; y < Height - 1; y++)  
  13.              {  
  14.                  System.Random MyRandom = new Random();  
  15.                  int k = MyRandom.Next(123456);  
  16.                  //像素块大小  
  17.                  int dx = x + k % 19;  
  18.                  int dy = y + k % 19;  
  19.                  if (dx >= Width)  
  20.                      dx = Width - 1;  
  21.                  if (dy >= Height)  
  22.                      dy = Height - 1;  
  23.                  pixel = oldBitmap.GetPixel(dx, dy);  
  24.                  newBitmap.SetPixel(x, y, pixel);  
  25.              }  
  26.          this.pictureBox1.Image = newBitmap;  
  27.      }  
  28.      catch (Exception ex)  
  29.      {  
  30.          MessageBox.Show(ex.Message, "信息提示");  
  31.      }  
  32.  }  
       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控件来显示图片,如下

[csharp] view plain copy
 
print?
  1. private void btnOpenImage_Click(object sender, EventArgs e)  
  2.       {  
  3.           OpenFileDialog ofd = new OpenFileDialog();  
  4.           ofd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";  
  5.           ofd.CheckFileExists = true;  
  6.           ofd.CheckPathExists = true;  
  7.           if (ofd.ShowDialog() == DialogResult.OK)  
  8.           {  
  9.               //pbxShowImage.ImageLocation = ofd.FileName;  
  10.               bmp = new Bitmap(ofd.FileName);  
  11.               if (bmp==null)  
  12.               {  
  13.                   MessageBox.Show("加载图片失败!", "错误");  
  14.                   return;  
  15.               }  
  16.               pbxShowImage.Image = bmp;  
  17.               ofd.Dispose();  
  18.           }  
  19.       }  
  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;
二、保存图像
[csharp] view plain copy
 
print?
  1. private void btnSaveImage_Click(object sender, EventArgs e)  
  2.      {  
  3.          if (bmp == null) return;  
  4.          SaveFileDialog sfd = new SaveFileDialog();  
  5.          sfd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";  
  6.          if (sfd.ShowDialog() == DialogResult.OK)  
  7.          {  
  8.              pbxShowImage.Image.Save(sfd.FileName);  
  9.              MessageBox.Show("保存成功!","提示");  
  10.              sfd.Dispose();  
  11.          }  
  12.      }  
   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类来做相关的处理。整个类的程序如下:

[csharp] view plain copy
 
print?
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Drawing;  
  6. using System.Drawing.Imaging;  
  7. using System.Windows.Forms;  
  8. namespace ImageElf  
  9. {  
  10.     class GrayBitmapData  
  11.     {  
  12.         public byte[,] Data;//保存像素矩阵  
  13.         public int Width;//图像的宽度  
  14.         public int Height;//图像的高度  
  15.         public GrayBitmapData()  
  16.         {  
  17.             this.Width = 0;  
  18.             this.Height = 0;  
  19.             this.Data = null;  
  20.         }  
  21.         public GrayBitmapData(Bitmap bmp)  
  22.         {  
  23.             BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);  
  24.             this.Width = bmpData.Width;  
  25.             this.Height = bmpData.Height;  
  26.             Data = new byte[Height, Width];  
  27.             unsafe  
  28.             {  
  29.                 byte* ptr = (byte*)bmpData.Scan0.ToPointer();  
  30.                 for (int i = 0; i < Height; i++)  
  31.                 {  
  32.                     for (int j = 0; j < Width; j++)  
  33.                     {  
  34.     //将24位的RGB彩色图转换为灰度图  
  35.                         int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));  
  36.                         Data[i, j] = (byte)temp;  
  37.                     }  
  38.                     ptr += bmpData.Stride - Width * 3;//指针加上填充的空白空间  
  39.                 }  
  40.             }  
  41.             bmp.UnlockBits(bmpData);  
  42.         }  
  43.         public GrayBitmapData(string path)  
  44.             : this(new Bitmap(path))  
  45.         {  
  46.         }  
  47.         public Bitmap ToBitmap()  
  48.         {  
  49.             Bitmap bmp=new Bitmap(Width,Height,PixelFormat.Format24bppRgb);  
  50.             BitmapData bmpData=bmp.LockBits(new Rectangle(0,0,Width,Height),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);  
  51.             unsafe  
  52.             {  
  53.                 byte* ptr=(byte*)bmpData.Scan0.ToPointer();  
  54.                 for(int i=0;i<Height;i++)  
  55.                 {  
  56.                     for(int j=0;j<Width;j++)  
  57.                     {  
  58.                         *(ptr++)=Data[i,j];  
  59.                         *(ptr++)=Data[i,j];  
  60.                         *(ptr++)=Data[i,j];  
  61.                     }  
  62.                     ptr+=bmpData.Stride-Width*3;  
  63.                 }  
  64.             }  
  65.             bmp.UnlockBits(bmpData);  
  66.             return bmp;  
  67.         }  
  68.         public void ShowImage(PictureBox pbx)  
  69.         {  
  70.             Bitmap b = this.ToBitmap();  
  71.             pbx.Image = b;  
  72.             //b.Dispose();  
  73.         }  
  74.         public void SaveImage(string path)  
  75.         {  
  76.             Bitmap b=ToBitmap();  
  77.             b.Save(path);  
  78.             //b.Dispose();  
  79.         }  
  80. //均值滤波  
  81.         public void AverageFilter(int windowSize)  
  82.         {  
  83.             if (windowSize % 2 == 0)  
  84.             {  
  85.                 return;  
  86.             }  
  87.             for (int i = 0; i < Height; i++)  
  88.             {  
  89.                 for (int j = 0; j < Width; j++)  
  90.                 {  
  91.                     int sum = 0;  
  92.                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)  
  93.                     {  
  94.                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)  
  95.                         {  
  96.                             int a = i + g, b = j + k;  
  97.                             if (a < 0) a = 0;  
  98.                             if (a > Height - 1) a = Height - 1;  
  99.                             if (b < 0) b = 0;  
  100.                             if (b > Width - 1) b = Width - 1;  
  101.                             sum += Data[a, b];  
  102.                         }  
  103.                     }  
  104.                     Data[i,j]=(byte)(sum/(windowSize*windowSize));  
  105.                 }  
  106.             }  
  107.         }  
  108. //中值滤波  
  109.         public void MidFilter(int windowSize)  
  110.         {  
  111.             if (windowSize % 2 == 0)  
  112.             {  
  113.                 return;  
  114.             }  
  115.             int[] temp = new int[windowSize * windowSize];  
  116.             byte[,] newdata = new byte[Height, Width];  
  117.             for (int i = 0; i < Height; i++)  
  118.             {  
  119.                 for (int j = 0; j < Width; j++)  
  120.                 {  
  121.                     int n = 0;  
  122.                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)  
  123.                     {  
  124.                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)  
  125.                         {  
  126.                             int a = i + g, b = j + k;  
  127.                             if (a < 0) a = 0;  
  128.                             if (a > Height - 1) a = Height - 1;  
  129.                             if (b < 0) b = 0;  
  130.                             if (b > Width - 1) b = Width - 1;  
  131.                             temp[n++]= Data[a, b];  
  132.                         }  
  133.                     }  
  134.                     newdata[i, j] = GetMidValue(temp,windowSize*windowSize);  
  135.                 }  
  136.             }  
  137.             for (int i = 0; i < Height; i++)  
  138.             {  
  139.                 for (int j = 0; j < Width; j++)  
  140.                 {  
  141.                     Data[i, j] = newdata[i, j];  
  142.                 }  
  143.             }  
  144.         }  
  145. //获得一个向量的中值  
  146.         private byte GetMidValue(int[] t, int length)  
  147.         {  
  148.             int temp = 0;  
  149.             for (int i = 0; i < length - 2; i++)  
  150.             {  
  151.                 for (int j = i + 1; j < length - 1; j++)  
  152.                 {  
  153.                     if (t[i] > t[j])  
  154.                     {  
  155.                         temp = t[i];  
  156.                         t[i] = t[j];  
  157.                         t[j] = temp;  
  158.                     }  
  159.                 }  
  160.             }  
  161.             return (byte)t[(length - 1) / 2];  
  162.         }  
  163. //一种新的滤波方法,是亮的更亮、暗的更暗  
  164.         public void NewFilter(int windowSize)  
  165.         {  
  166.             if (windowSize % 2 == 0)  
  167.             {  
  168.                 return;  
  169.             }  
  170.             for (int i = 0; i < Height; i++)  
  171.             {  
  172.                 for (int j = 0; j < Width; j++)  
  173.                 {  
  174.                     int sum = 0;  
  175.                     for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)  
  176.                     {  
  177.                         for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)  
  178.                         {  
  179.                             int a = i + g, b = j + k;  
  180.                             if (a < 0) a = 0;  
  181.                             if (a > Height - 1) a = Height - 1;  
  182.                             if (b < 0) b = 0;  
  183.                             if (b > Width - 1) b = Width - 1;  
  184.                             sum += Data[a, b];  
  185.                         }  
  186.                     }  
  187.                     double avg = (sum+0.0) / (windowSize * windowSize);  
  188.                     if (avg / 255 < 0.5)  
  189.                     {  
  190.                         Data[i, j] = (byte)(2 * avg / 255 * Data[i, j]);  
  191.                     }  
  192.                     else  
  193.                     {  
  194.                         Data[i,j]=(byte)((1-2*(1-avg/255.0)*(1-Data[i,j]/255.0))*255);  
  195.                     }  
  196.                 }  
  197.             }  
  198.         }  
  199. //直方图均衡  
  200.         public void HistEqual()  
  201.         {  
  202.             double[] num = new double[256] ;  
  203.             for(int i=0;i<256;i++) num[i]=0;  
  204.             for (int i = 0; i < Height; i++)  
  205.             {  
  206.                 for (int j = 0; j < Width; j++)  
  207.                 {  
  208.                     num[Data[i, j]]++;  
  209.                 }  
  210.             }  
  211.             double[] newGray = new double[256];  
  212.             double n = 0;  
  213.             for (int i = 0; i < 256; i++)  
  214.             {  
  215.                 n += num[i];  
  216.                 newGray[i] = n * 255 / (Height * Width);  
  217.             }  
  218.             for (int i = 0; i < Height; i++)  
  219.             {  
  220.                 for (int j = 0; j < Width; j++)  
  221.                 {  
  222.                     Data[i,j]=(byte)newGray[Data[i,j]];  
  223.                 }  
  224.             }  
  225.         }  
  226. }  
  227. }  
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进行一系列的操作就是对图片的操作处理。在窗口上,我们可以使用
一个按钮来做各种调用:

 

[csharp] view plain copy
 
print?
  1. //均值滤波  
  2.         private void btnAvgFilter_Click(object sender, EventArgs e)  
  3.         {  
  4.             if (bmp == null) return;  
  5.             GrayBitmapData gbmp = new GrayBitmapData(bmp);  
  6.             gbmp.AverageFilter(3);  
  7.             gbmp.ShowImage(pbxShowImage);  
  8.         }  
  9. //转换为灰度图  
  10.         private void btnToGray_Click(object sender, EventArgs e)  
  11.         {  
  12.             if (bmp == null) return;  
  13.             GrayBitmapData gbmp = new GrayBitmapData(bmp);  
  14.             gbmp.ShowImage(pbxShowImage);  
  15.         }  
  16.    
//均值滤波
        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.图片亮度处理

[csharp] view plain copy
 
print?
  1. private void btn_Grap_Click(object sender, EventArgs e)  
  2.        {  
  3.            //亮度百分比  
  4.            int percent = 50;  
  5.            Single v = 0.006F * percent;      
  6.            Single[][] matrix = {           
  7.                new Single[] { 1, 0, 0, 0, 0 },           
  8.                new Single[] { 0, 1, 0, 0, 0 },            
  9.                new Single[] { 0, 0, 1, 0, 0 },           
  10.                new Single[] { 0, 0, 0, 1, 0 },           
  11.                new Single[] { v, v, v, 0, 1 }       
  12.            };      
  13.            System.Drawing.Imaging.ColorMatrix cm = new System.Drawing.Imaging.ColorMatrix(matrix);  
  14.            System.Drawing.Imaging.ImageAttributes attr = new System.Drawing.Imaging.ImageAttributes();      
  15.            attr.SetColorMatrix(cm);      
  16.            //Image tmp   
  17.            Image tmp = Image.FromFile("1.png");  
  18.   
  19.            this.pictureBox_Src.Image = Image.FromFile("1.png");  
  20.   
  21.            Graphics g = Graphics.FromImage(tmp);    
  22.            try    
  23.            {  
  24.                Rectangle destRect = new Rectangle(0, 0, tmp.Width, tmp.Height);          
  25.                g.DrawImage(tmp, destRect, 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel, attr);      
  26.            }      
  27.            finally      
  28.            {          
  29.                g.Dispose();      
  30.            }  
  31.   
  32.            this.pictureBox_Dest.Image = (Image)tmp.Clone();  
  33.        }  
 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

[csharp] view plain copy
 
print?
  1. private void btn_Screen_Click(object sender, EventArgs e)  
  2.       {  
  3.           Image myImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);  
  4.           Graphics g = Graphics.FromImage(myImage);  
  5.           g.CopyFromScreen(new Point(0, 0), new Point(0, 0), new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));  
  6.           //IntPtr dc1 = g.GetHdc();      //此处这两句多余,具体看最后GetHdc()定义  
  7.           //g.ReleaseHdc(dc1);             
  8.           g.Dispose();  
  9.           this.pictureBox_Src.SizeMode = PictureBoxSizeMode.StretchImage;  
  10.           this.pictureBox_Src.Image = myImage;  
  11.           myImage.Save("Screen", ImageFormat.Png);  
  12.    }  
  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.翻转

 

[csharp] view plain copy
 
print?
  1. private void btn_RotateFlip_Click(object sender, EventArgs e)  
  2.      {  
  3.          this.pictureBox_Src.Image = Image.FromFile("1.png");  
  4.   
  5.          Image tmp = Image.FromFile("1.png");  
  6.   
  7.          tmp.RotateFlip(RotateFlipType.Rotate90FlipNone);  
  8.          this.pictureBox_Dest.Image = tmp;  
  9.      }  
   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的图片上画矩形

[csharp] view plain copy
 
print?
  1. private int intStartX = 0;  
  2.       private int intStartY = 0;  
  3.       private bool isMouseDraw = false;  
  4.   
  5.       private void pictureBox_Src_MouseDown(object sender, MouseEventArgs e)  
  6.       {  
  7.           isMouseDraw = true;  
  8.   
  9.           intStartX = e.X;  
  10.           intStartY = e.Y;  
  11.       }  
  12.   
  13.       private void pictureBox_Src_MouseMove(object sender, MouseEventArgs e)  
  14.       {  
  15.           if (isMouseDraw)  
  16.           {  
  17.               try  
  18.               {  
  19.                   //Image tmp = Image.FromFile("1.png");  
  20.                   Graphics g = this.pictureBox_Src.CreateGraphics();  
  21.                   //清空上次画下的痕迹  
  22.                   g.Clear(this.pictureBox_Src.BackColor);  
  23.                   Brush brush = new SolidBrush(Color.Red);  
  24.                   Pen pen = new Pen(brush, 1);  
  25.                   pen.DashStyle = DashStyle.Solid;  
  26.                   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)));  
  27.                   g.Dispose();  
  28.                   //this.pictureBox_Src.Image = tmp;  
  29.               }  
  30.               catch (Exception ex)  
  31.               {  
  32.                   ex.ToString();  
  33.               }  
  34.           }  
  35.       }  
  36.   
  37.       private void pictureBox_Src_MouseUp(object sender, MouseEventArgs e)  
  38.       {  
  39.           isMouseDraw = false;  
  40.   
  41.           intStartX = 0;  
  42.           intStartY = 0;  
  43.       }  
  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.取灰度

 

[csharp] view plain copy
 
print?
  1. private void btn_GetGray_Click(object sender, EventArgs e)  
  2.        {  
  3.            this.pictureBox_Src.Image = Image.FromFile("1.png");  
  4.            Bitmap currentBitmap = new Bitmap(this.pictureBox_Src.Image);  
  5.            Graphics g = Graphics.FromImage(currentBitmap);  
  6.            ImageAttributes ia = new ImageAttributes();  
  7.            float[][] colorMatrix =   {      
  8.                new   float[]   {0.299f,   0.299f,   0.299f,   0,   0},  
  9.                new   float[]   {0.587f,   0.587f,   0.587f,   0,   0},  
  10.                new   float[]   {0.114f,   0.114f,   0.114f,   0,   0},  
  11.                new   float[]   {0,   0,   0,   1,   0},  
  12.                new   float[]   {0,   0,   0,   0,   1}  
  13.            };  
  14.            ColorMatrix cm = new ColorMatrix(colorMatrix);  
  15.            ia.SetColorMatrix(cm, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);  
  16.            g.DrawImage(currentBitmap, new Rectangle(0, 0, currentBitmap.Width, currentBitmap.Height), 0, 0, currentBitmap.Width, currentBitmap.Height, GraphicsUnit.Pixel, ia);  
  17.            this.pictureBox_Dest.Image = (Image)(currentBitmap.Clone());  
  18.            g.Dispose();  
  19.        }  
 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 关联的设备上下文的句柄。

实现

IDeviceContext.GetHdc()

备注


设备上下文是一个基于 GDI 的 Windows 结构,它定义一组图形对象及其关联的特性,以及影响输出的图形模式。 此方法返回该设备上下文(字体除外)。由于未选择字体,使用 GetHdc 方法返回的句柄对 FromHdc 方法进行调用将会失败。

GetHdc 方法调用和 ReleaseHdc 方法调用必须成对出现。 在 GetHdc 和 ReleaseHdc 方法对的范围内,通常仅调用 GDI 函数。 在该范围内对 Graphics(它产生 hdc 参数)的 GDI+ 方法的调用因 ObjectBusy 错误而失败。 此外,GDI+ 忽略后续操作中对 hdc 参数的 Graphics 所做的所有状态更改。

示例


下面的代码示例设计为与 Windows 窗体一起使用,它需要 PaintEventArgse,即 Paint 事件处理程序的一个参数。 该示例演示如何调用 Windows GDI 函数以执行与 GDI+ Graphics 方法相同的任务。 代码执行下列操作:

  • 为 Windows DLL 文件 gdi32.dll 定义互操作性 DllImportAttribute 特性。 此 DLL 包含所需的 GDI 函数。
  • 将该 DLL 中的 Rectangle 函数定义为外部函数。
  • 创建一支红色钢笔。
  • 利用该钢笔,使用 GDI+ DrawRectangle 方法将矩形绘制到屏幕。
  • 定义内部指针类型变量 hdc 并将它的值设置为窗体的设备上下文句柄。
  • 使用 GDI Rectangle 函数将矩形绘制到屏幕。

释放由 hdc 参数表示的设备上下文。

[csharp] view plain copy
 
print?
  1. public class GDI  
  2. {  
  3.     [System.Runtime.InteropServices.DllImport("gdi32.dll")]  
  4.     internal static extern bool Rectangle(  
  5.        IntPtr hdc,  
  6.        int ulCornerX, int ulCornerY,  
  7.        int lrCornerX, int lrCornerY);  
  8. }  
  9.    
  10. [System.Security.Permissions.SecurityPermission(  
  11. System.Security.Permissions.SecurityAction.LinkDemand, Flags =  
  12. System.Security.Permissions.SecurityPermissionFlag.UnmanagedCode)]             
  13. private void GetHdcForGDI1(PaintEventArgs e)  
  14. {  
  15.     // Create pen.  
  16.     Pen redPen = new Pen(Color.Red, 1);  
  17.    
  18.     // Draw rectangle with GDI+.  
  19.     e.Graphics.DrawRectangle(redPen, 10, 10, 100, 50);  
  20.    
  21.     // Get handle to device context.  
  22.     IntPtr hdc = e.Graphics.GetHdc();  
  23.    
  24.     // Draw rectangle with GDI using default pen.  
  25.     GDI.Rectangle(hdc, 10, 70, 110, 120);  
  26.    
  27.     // Release handle to device context.  
  28.     e.Graphics.ReleaseHdc(hdc);  
  29. }  
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);
}
posted on 2016-10-21 23:27  張暁磊  阅读(354)  评论(0编辑  收藏  举报