//灰度化 private Bitmap bitmapGray(Bitmap bitmap, GrayMode mode) { if (bitmap == null) { return(null); } Bitmap newBitmap = bitmap.Clone() as Bitmap; int width = newBitmap.Width; int height = newBitmap.Height; BitmapData bitmapData = newBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, newBitmap.PixelFormat); int stride = bitmapData.Stride;//stride是一整行的宽度 32色图情况下为width*4 IntPtr ptr = bitmapData.Scan0; byte[] src = new byte[stride * height]; Marshal.Copy(ptr, src, 0, stride * height); for (int i = 0; i < height; i++) { for (int j = 0; j < stride; j += 4) { int k = i * stride; switch (mode) { case GrayMode.COMPONENT_RED: src[k + j + 1] = src[k + j + 2] = src[k + j]; break; case GrayMode.COMPONENT_GREEN: src[k + j] = src[k + j + 2] = src[k + j + 1]; break; case GrayMode.COMPONENT_BLUE: src[k + j] = src[k + j + 1] = src[k + j + 2]; break; case GrayMode.AVERAGE_RGB: src[k + j] = src[k + j + 1] = src[k + j + 2] = (byte)((src[k + j] + src[k + j + 1] + src[k + j + 2]) / 3); break; case GrayMode.MAX_RGB: src[k + j] = src[k + j + 1] = src[k + j + 2] = Math.Max(Math.Max(src[k + j], src[k + j + 1]), src[k + j + 2]); break; case GrayMode.WEIGHT_RGB: byte sum = (byte)(src[k + j] * 0.299 + src[k + j + 1] * 0.578 + src[k + j + 2] * 0.114); src[k + j + 1] = src[k + j + 2] = src[k + j] = sum; break; } } } Marshal.Copy(src, 0, ptr, stride * height); newBitmap.UnlockBits(bitmapData); return(newBitmap); }
/// <summary> /// 获取灰度值位图(内存处理方法) /// </summary> /// <param name="bitmap">转换位图</param> /// <param name="mode">处理模式</param> /// <returns>处理结果位图</returns> public static Bitmap GrayscaleBitmap(Bitmap bitmap, GrayMode mode = GrayMode.Perceived) { if (bitmap == null) { return(null); } Bitmap srcBitmap = (Bitmap)bitmap.Clone(); int width = srcBitmap.Width, height = srcBitmap.Height; Rectangle rect = new Rectangle(0, 0, width, height); //将Bitmap锁定到系统内存中,获得BitmapData BitmapData srcBmData = srcBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); //创建Bitmap Bitmap dstBitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed); BitmapData dstBmData = dstBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); // get palette ColorPalette cp = dstBitmap.Palette; // init palette for (int i = 0; i < 256; i++) { cp.Entries[i] = Color.FromArgb(i, i, i); } dstBitmap.Palette = cp; //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行 IntPtr srcPtr = srcBmData.Scan0, dstPtr = dstBmData.Scan0; //将Bitmap对象的信息存放到byte数组中 int src_bytes = srcBmData.Stride * height, dst_bytes = dstBmData.Stride * height; byte[] srcValues = new byte[src_bytes], dstValues = new byte[dst_bytes]; //复制GRB信息到byte数组 Marshal.Copy(srcPtr, srcValues, 0, src_bytes); Marshal.Copy(dstPtr, dstValues, 0, dst_bytes); //根据Y=0.299*R+0.114*G+0.587B,Y为亮度 for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { //只处理每行中图像像素数据,舍弃未用空间 //注意位图结构中RGB按BGR的顺序存储 int k = 3 * j; byte r = srcValues[i * srcBmData.Stride + k + 2]; byte g = srcValues[i * srcBmData.Stride + k + 1]; byte b = srcValues[i * srcBmData.Stride + k]; // 灰度值提取 byte temp = 0; switch (mode) { case GrayMode.AverageMethod: temp = (byte)((r + g + b) / 3); break; case GrayMode.Perceived: temp = (byte)(r * 0.299 + g * 0.587 + b * 0.114); break; case GrayMode.TakeGreen: temp = g; break; } dstValues[i * dstBmData.Stride + j] = temp; } } Marshal.Copy(dstValues, 0, dstPtr, dst_bytes); //解锁位图 srcBitmap.UnlockBits(srcBmData); dstBitmap.UnlockBits(dstBmData); return(dstBitmap); }