日期:2014-05-17  浏览次数:20807 次

【求助】如何输出 8位 灰度图像

 输入一个24位的RGB彩色图像,容易通过计算将其灰度化,但这只是视觉上灰度化了,如何存储成为8位的灰度图像??
 使用了8bppindex 创建,但结果却成了具有256种彩色的图像。

------解决方案--------------------
把颜色索引表置为灰阶就可以了,请参考所贴代码。

为代码清晰用了GetPixel(),它是很慢的函数。图像稍大一点建议用LockBit把图像放到系统内存中操作。亮度计算这里用了简单平均,你可以选择你认为合适的算法。

C# code

//...
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
//...

{
    Bitmap bmp = new Bitmap("my.jpg");

    // 每一扫描线必须是4 byte的倍数。
        int stride = ((bmp.Width - 1) & 0x00FFFFFC) + 4;
    byte[] intensities = new byte[ stride * bmp.Height];

    // 把计算出来的亮度放到准备好的内存数组中
        for(int y = 0; y<bmp.Height; y++)
    {
        for(int x = 0; x<bmp.Width; x++)
        {
            Color c = bmp.GetPixel(x,y);
            intensities[y * stride + x] = (byte)((c.R + c.G + c.B) / 3);
        }
    }

    // 构置一个8bit的索引图像,直接指定图像数据
        GCHandle gch = GCHandle.Alloc(intensities, GCHandleType.Pinned);
    Bitmap grayscale = new Bitmap(
        bmp.Width,
        bmp.Height,
        stride,
        PixelFormat.Format8bppIndexed,
        gch.AddrOfPinnedObject());
    gch.Free();

    // 重置颜色索引表为灰阶
        ColorPalette palette = grayscale.Palette;
    for (int i = 0; i < palette.Entries.Length; i++)
    {
        palette.Entries[i] = Color.FromArgb(i, i, i);
    }
    grayscale.Palette = palette;

    grayscale.Save("gray.bmp");
}