예제 #1
0
        //灰度化
        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);
        }
예제 #2
0
        /// <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);
        }