c# 内存法二值化图像

之前在网上看的一些方法都是通过指针来操作的,下面这个方法是通过c#内存操作的

 保存下来,方便以后自己查看

 1    private static Bitmap PBinary(Bitmap src, int v)
 2         {
 3             int w = src.Width;
 4             int h = src.Height;
 5             Bitmap dstBitmap = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 6             System.Drawing.Imaging.BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 7             System.Drawing.Imaging.BitmapData dstData = dstBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
 8             int stride = srcData.Stride;
 9             var srcBytes = new byte[h * stride];//这个地方通过高度×行跨距来计算需要的数组大小,如果用宽×高×3来计算的话会不准。
10             var dstBytes = new byte[h * stride];
11             IntPtr pIn = srcData.Scan0;
12             IntPtr pOut = dstData.Scan0;
13             Marshal.Copy(pIn, srcBytes, 0, srcBytes.Length);           
14 
15             for (int i = 0; i < h; i++)
16             {
17                 for (int j = 0; j < srcData.Stride - 3; j = j + 3)//这个地方+3是因为我默认的图片是24位的,24位的一个像素点用三个字节来表示,如果是32位的,则是4个字节来存储。就要改成4
18                 {
19                     var r = srcBytes[i * stride + j + 2];
20                     var g = srcBytes[i * stride + j + 1];
21                     var b = srcBytes[i * stride + j];
22 
23                     dstBytes[i * stride + j] = dstBytes[i * stride + j + 1] = dstBytes[i * stride + j + 2] =
24                         (byte)(((byte)(0.2125 * r + 0.7154 * g + 0.0721 * b) >= v) ? 255 : 0);//这个地方是计算出一个像素点的平均灰度,然后判断是否大于阀值。
25                 }
26             }
27             Marshal.Copy(dstBytes, 0, pOut, dstBytes.Length);
28             src.UnlockBits(srcData);
29             dstBitmap.UnlockBits(dstData);          
42 return dstBitmap; 44 }

 

posted @ 2015-07-31 16:41  无忌他爹  阅读(267)  评论(0编辑  收藏  举报