C# 在C语言中减少位图位大小#

C# 在C语言中减少位图位大小#,c#,bitmap,C#,Bitmap,我正在使用C#,并且在对象位图中存储了一个图像 现在我想把这个图像转换成8位灰度,然后再转换成4位灰度图像 你有什么技巧可以做到这一点吗?在.NET位图格式中,没有8位或4位灰度图像。支持的格式由枚举。但是,您可以通过创建索引图像(8bppIndexed或4bppIndexed)来创建4位或8位图像,其中调色板中的每个条目都是灰度值 此代码获取位图并创建一个副本,作为具有灰度值的8bpp索引图像: public static Bitmap BitmapToGrayscale(Bitmap

我正在使用C#,并且在对象位图中存储了一个图像

现在我想把这个图像转换成8位灰度,然后再转换成4位灰度图像


你有什么技巧可以做到这一点吗?

在.NET位图格式中,没有8位或4位灰度图像。支持的格式由枚举。但是,您可以通过创建索引图像(8bppIndexed或4bppIndexed)来创建4位或8位图像,其中调色板中的每个条目都是灰度值

此代码获取位图并创建一个副本,作为具有灰度值的8bpp索引图像:

    public static Bitmap BitmapToGrayscale(Bitmap source)
    {
        // Create target image.
        int width = source.Width;
        int height = source.Height;
        Bitmap target = new Bitmap(width,height,PixelFormat.Format8bppIndexed);
        // Set the palette to discrete shades of gray
        ColorPalette palette = target.Palette;            
        for(int i = 0 ; i < palette.Entries.Length ; i++)
        {                
            palette.Entries[i] = Color.FromArgb(0,i,i,i);
        }
        target.Palette = palette;

        // Lock bits so we have direct access to bitmap data
        BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
                                                ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
        BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
                                                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

        unsafe
        {
            for(int r = 0 ; r < height ; r++)
            {
                byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
                byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
                for(int c = 0 ; c < width ; c++)
                {
                    byte colorIndex = (byte) (((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11));
                    *pTarget = colorIndex;
                    pTarget++;
                    pSource += 3;
                }
            }
        }

        target.UnlockBits(targetData);
        source.UnlockBits(sourceData);
        return target;
    }
公共静态位图BitmapToGrayscale(位图源)
{
//创建目标图像。
int-width=source.width;
int height=源高度;
位图目标=新位图(宽度、高度、PixelFormat.Format8Bppined);
//将调色板设置为灰色的离散阴影
ColorPalette=target.palete;
对于(int i=0;i
为了生成4Bpp图像,您需要使用PixelFormat.Format4bppIndexed创建目标,然后将调色板设置为16个离散灰度。最后,在循环中,应该将值2规格化为0-15之间的值,并将每2个像素值打包为一个字节

这是制作4bpp灰度图像的修改代码:

    public static Bitmap BitmapToGrayscale4bpp(Bitmap source)
    {
        // Create target image.
        int width = source.Width;
        int height = source.Height;
        Bitmap target = new Bitmap(width,height,PixelFormat.Format4bppIndexed);
        // Set the palette to discrete shades of gray
        ColorPalette palette = target.Palette;            
        for(int i = 0 ; i < palette.Entries.Length ; i++)
        {
            int cval = 17*i;
            palette.Entries[i] = Color.FromArgb(0,cval,cval,cval);
        }
        target.Palette = palette;

        // Lock bits so we have direct access to bitmap data
        BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
                                                ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed);
        BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
                                                ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);

        unsafe
        {
            for(int r = 0 ; r < height ; r++)
            {
                byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
                byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
                byte prevValue = 0;
                for(int c = 0 ; c < width ; c++)
                {
                    byte colorIndex = (byte) ((((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11)) / 16);
                    if (c % 2 == 0)
                        prevValue = colorIndex;
                    else
                        *(pTarget++) = (byte)(prevValue | colorIndex << 4);

                    pSource += 3;
                }
            }
        }

        target.UnlockBits(targetData);
        source.UnlockBits(sourceData);
        return target;
    }
公共静态位图BitmapToGrayscale4bpp(位图源)
{
//创建目标图像。
int-width=source.width;
int height=源高度;
位图目标=新位图(宽度、高度、像素格式.Format4bppIndexed);
//将调色板设置为灰色的离散阴影
ColorPalette=target.palete;
对于(int i=0;i*(pTarget++)=(byte)(prevValue | colorIndex
BitmapToGrayscale4bpp
的最后一部分有一个小错误:
(byte)(prevValue | colorIndex