【问题标题】:Save a 32-bit Bitmap as 1-bit .bmp file in C#在 C# 中将 32 位位图另存为 1 位 .bmp 文件
【发布时间】:2010-04-04 13:47:19
【问题描述】:

在 C# 中将 32 位位图转换并保存为 1 位(黑/白).bmp 文件的最简单方法是什么?

【问题讨论】:

    标签: c# bitmap


    【解决方案1】:

    使用Clone()实现此目的的最简单方法

    using System.Drawing.Imaging;
    
    var original = //your source image;
    var rectangle = new Rectangle(0, 0, original.Width, original.Height);
    
    var bmp1bpp = original.Clone(rectangle, PixelFormat.Format1bppIndexed);
    

    声明这可能不是最快的方法,有更快的方法来做到这一点

    【讨论】:

    • 这绝对是更简单的方法
    【解决方案2】:

    此代码将完成工作:

    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
    ...
    
    public static Bitmap BitmapTo1Bpp(Bitmap img) {
      int w = img.Width;
      int h = img.Height;
      Bitmap bmp = new Bitmap(w, h, PixelFormat.Format1bppIndexed);
      BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
      byte[] scan = new byte[(w + 7) / 8];
      for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
          if (x % 8 == 0) scan[x / 8] = 0;
          Color c = img.GetPixel(x, y);
          if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
        }
        Marshal.Copy(scan, 0, (IntPtr)((long)data.Scan0 + data.Stride * y), scan.Length);
      }
      bmp.UnlockBits(data);
      return bmp;
    }
    

    如有必要,您可以通过使用不安全代码替换 GetPixel() 方法来加快速度。

    【讨论】:

    • 如果您已经锁定了这些位,您不妨 Marshal.Copy 将所有数据复制到一个 byte[] 并一次完成所有操作。这将为您节省 getpixel 和重复的 marshal.copy 开销。
    • 没那么简单,源图的ImageFormat很重要。
    • Ron,如果您在源图像中有一个非最小步幅,除非您在目标图像中具有相同的步幅,否则这将不起作用。 (步幅 >= 宽度 * bytesPerPixel)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多