c# 24位圖像轉8位灰度圖像(數組方式)

http://blog.csdn.net/slzlren/article/details/4318400

現在網上的例子多數都是24位圖像轉24位灰度圖的,即使有轉8位灰度的,也是通過GetPixel(轉換速度太慢)或者指針方式(一來C#並不推薦這種模式,二來我也沒有學過c++之類的對指針實在不熟悉)來實現的,而沒有c#推薦的數組方式的.

因為bmp在內存中儲存的時候,每行都是必須是4的倍數才可以,開始忘記處理這個間隙,結果導致有的圖片可以正常轉換,有的圖片就發生圖像扭曲.

處理完這個後,又發現輸出的都是一些帶顏色的色點組成的圖像,不是灰度圖,經過查資料才知道輸出的是偽彩色,要轉成灰度才可以.

全部代碼如下

        /// <summary>
        /// 灰度處理(BitmapData類)
        /// </summary>
        /// <returns>輸出8位灰度圖片</returns>
        public static Bitmap 灰度處理(Bitmap 圖像)
        {
            Bitmap bmp = new Bitmap(圖像.Width, 圖像.Height, PixelFormat.Format8bppIndexed);

            //設定實例BitmapData相關信息
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

            BitmapData data = 圖像.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            //鎖定bmp到系統內存中
            BitmapData data2 = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

            //獲取位圖中第一個像素數據的地址
            IntPtr ptr = data.Scan0;
            IntPtr ptr2 = data2.Scan0;

            int numBytes = data.Stride * data.Height;      
            int numBytes2 = data2.Stride * data2.Height;

            int n2 = data2.Stride - bmp.Width;  顯示寬度與掃描線寬度的間隙

            byte[] rgbValues = new byte[numBytes];
            byte[] rgbValues2 = new byte[numBytes2];
            //將bmp數據Copy到申明的數組中
            Marshal.Copy(ptr, rgbValues, 0, numBytes);
            Marshal.Copy(ptr2, rgbValues2, 0, numBytes2);

            int n = 0;

            for (int y = 0; y < bmp.Height; y++)
            {
                for (int x = 0; x < bmp.Width * 3; x += 3)
                {
                    int i = data.Stride * y + x;

                    double value = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114; //計算灰度

                    rgbValues2[n] = (byte)value;

                    n++;
                }
                n += n2; //跳過差值
            }

            //將數據Copy到內存指針
            Marshal.Copy(rgbValues, 0, ptr, numBytes);
            Marshal.Copy(rgbValues2, 0, ptr2, numBytes2);

             下面的代碼是為了修改生成位圖的索引表,從偽彩修改為灰度
            ColorPalette tempPalette;
            using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
            {
                tempPalette = tempBmp.Palette;
            }
            for (int i = 0; i < 256; i++)
            {
                tempPalette.Entries[i] = Color.FromArgb(i, i, i);
            }

            bmp.Palette = tempPalette;


            //從系統內存解鎖bmp
            圖像.UnlockBits(data);
            bmp.UnlockBits(data2);

            return bmp;
        }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值