之前在网上看的一些方法都是通过指针来操作的,下面这个方法是通过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 }
时间: 2024-10-20 12:52:10