【问题标题】:Convert 32-bit Bitmap to 8-bit (both color and grayscale)将 32 位位图转换为 8 位(彩色和灰度)
【发布时间】:2017-05-10 11:30:45
【问题描述】:

我有一个带有PixelFormatFormat32bppRgb 的System.Drawing.Bitmap。 我想把这张图片转换成8bit的位图。

以下是将32位图像转换为8位灰度图像的代码:

        public static Bitmap ToGrayscale(Bitmap bmp)
        {
            int rgb;
            System.Drawing.Color c;

            for (int y = 0; y < bmp.Height; y++)
                for (int x = 0; x < bmp.Width; x++)
                {
                    c = bmp.GetPixel(x, y);
                    rgb = (int)((c.R + c.G + c.B) / 3);
                    bmp.SetPixel(x, y, System.Drawing.Color.FromArgb(rgb, rgb, rgb));
                }
            return bmp;
        }

但是,我最终得到的 Bitmap 仍然具有 Format32bppRgb 的 PixelFormat 属性。

还有,

  • 如何将 32 位彩色图像转换为 8 位彩色图像?

感谢您的任何意见!

相关。
- Convert RGB image to RGB 16-bit and 8-bit
- C# - How to convert an Image into an 8-bit color Image?
- C# Convert Bitmap to indexed colour format
- Color Image Quantization in .NET
- quantization (Reduction of colors of image)
- The best way to reduce quantity of colors in bitmap palette

【问题讨论】:

标签: c# .net system.drawing


【解决方案1】:

您必须创建(并返回)位图的新实例。

PixelFormat在Bitmap的构造函数中指定,不能更改。

编辑: 基于this answer on MSDN的示例代码:

    public static Bitmap ToGrayscale(Bitmap bmp) {
        var result = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed);

        BitmapData data = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

        // Copy the bytes from the image into a byte array
        byte[] bytes = new byte[data.Height * data.Stride];
        Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

        for (int y = 0; y < bmp.Height; y++) {
            for (int x = 0; x < bmp.Width; x++) {
                var c = bmp.GetPixel(x, y);
                var rgb = (byte)((c.R + c.G + c.B) / 3);

                bytes[x * data.Stride + y] = rgb;
            }
        }

        // Copy the bytes from the byte array into the image
        Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);

        result.UnlockBits(data);

        return result;
    }

【讨论】:

  • 谢谢。如果我使用 PixelFormat Format8bppIndexed 创建一个新位图,我不能使用 SetPixel 方法,因为它会导致异常:SetPixel is not supported for images with indexed pixel formats.
  • bytes[x * data.Stride + y] = rgb ...跨度不是一行的宽度吗?我猜 x 和 y 必须交换,但我没有测试它......所以只是为了澄清。
  • 应该是bytes[x * data.Height + y] = rgb,否则会crash with index out of array error。
  • 也许它“取决于”。 bytes[y * data.Stride + w] = rgb 为我工作。
猜你喜欢
  • 1970-01-01
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 2018-04-18
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多