分享

c# 24位图像转8位灰度图像(数组方式)

 ytkomn 2011-09-28

现在网上的例子多数都是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;  

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多