【问题标题】:converting bitmap to 8bpp grayscale outputs as 8bpp coloured index in c#将位图转换为 8bpp 灰度输出作为 c# 中的 8bpp 彩色索引
【发布时间】:2019-02-10 19:08:27
【问题描述】:

我正在尝试使用下面的代码将位图转换为 8bpp 灰度

private Bitmap ConvertPixelformat(ref Bitmap Bmp)
{
       Bitmap myBitmap = new Bitmap(Bmp);
        // Clone a portion of the Bitmap object.
        Rectangle cloneRect = new Rectangle(0, 0, Bmp.Width, Bmp.Height);
        PixelFormat format = PixelFormat.Format8bppIndexed;
        Bitmap cloneBitmap = myBitmap.Clone(cloneRect, format);
        var pal = cloneBitmap.Palette;

        for (i = 0; i < cloneBitmap.Palette.Entries.Length; ++i)
        {
            var entry = cloneBitmap.Palette.Entries[i];
            var gray = (int)(0.30 * entry.R + 0.59 * entry.G + 0.11 * entry.B);
            pal.Entries[i] = Color.FromArgb(gray, gray, gray);
        }
        cloneBitmap.Palette = pal;
        cloneBitmap.SetResolution(500.0F, 500.0F);
        return cloneBitmap;
}

检查位图图像的属性显示位深度已正确设置为 8bpp,但不是灰度,而是彩色索引 8bpp。请指导如何做。

【问题讨论】:

  • 看起来对吗?不确定您的调色板的创建方式。普通的grayscale Palette 将具有所有值。如果克隆人有任何机会从调色板上拾起,它必须首先在那里。也许你需要 DrawImage,但我不确定那里..
  • @TaW 是的。看来我需要修改代码以输出灰度 8bpp 位图

标签: c# image image-processing bitmap


【解决方案1】:

检查以下代码:

    public static unsafe Bitmap ToGrayscale(Bitmap colorBitmap)
    {
        int Width = colorBitmap.Width;
        int Height = colorBitmap.Height;

        Bitmap grayscaleBitmap = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);

        grayscaleBitmap.SetResolution(colorBitmap.HorizontalResolution,
                             colorBitmap.VerticalResolution);

        ///////////////////////////////////////
        // Set grayscale palette
        ///////////////////////////////////////
        ColorPalette colorPalette = grayscaleBitmap.Palette;
        for (int i = 0; i < colorPalette.Entries.Length; i++)
        {
            colorPalette.Entries[i] = Color.FromArgb(i, i, i);
        }
        grayscaleBitmap.Palette = colorPalette;
        ///////////////////////////////////////
        // Set grayscale palette
        ///////////////////////////////////////
        BitmapData bitmapData = grayscaleBitmap.LockBits(
            new Rectangle(Point.Empty, grayscaleBitmap.Size),
            ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

        Byte* pPixel = (Byte*)bitmapData.Scan0;

        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                Color clr = colorBitmap.GetPixel(x, y);

                Byte byPixel = (byte)((30 * clr.R + 59 * clr.G + 11 * clr.B) / 100);

                pPixel[x] = byPixel;
            }

            pPixel += bitmapData.Stride;
        }

        grayscaleBitmap.UnlockBits(bitmapData);

        return grayscaleBitmap;
    }

此代码将彩色图像转换为灰度图像。

【讨论】:

  • 8bpp 完全可以是非灰度的……事实上,System.Drawing 中实际上并没有针对“灰度 8bpp”的任何特定类型。这完全取决于调色板,您的代码专门将其设置为灰色。
  • @Nyerguds,告诉我如何创建 Lena 的 8bpp 彩色图像。
  • 唯一棘手的一点是获得一个好的调色板,这通常是用 K-means 聚类方法完成的(我一直想研究很久但还没有得到解决的方法) .但是有很多方法可以做到)。但是一旦你知道了,你只需要使用笛卡尔距离将图像的像素匹配到它们最近的调色板匹配。这一点都不难。
猜你喜欢
  • 2019-12-03
  • 1970-01-01
  • 2013-02-10
  • 1970-01-01
  • 2011-09-15
  • 2018-04-18
  • 2023-03-03
  • 2011-02-05
  • 2021-12-13
相关资源
最近更新 更多