从图像创建 1bpp 蒙版

发布于 2024-07-09 05:57:43 字数 305 浏览 4 评论 0原文

如何在 C# 中使用 GDI 从图像创建每像素 1 位的掩码? 我尝试创建蒙版的图像保存在 System.Drawing.Graphics 对象中。

我见过在循环中使用 Get/SetPixel 的示例,速度太慢。 我感兴趣的方法是仅使用 BitBlits 的方法,例如 this。 我只是无法让它在 C# 中工作,非常感谢任何帮助。

How do you create a 1 bit per pixel mask from an image using GDI in C#? The image I am trying to create the mask from is held in a System.Drawing.Graphics object.

I have seen examples that use Get/SetPixel in a loop, which are too slow. The method that interests me is one that uses only BitBlits, like this. I just can't get it to work in C#, any help is much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

东走西顾 2024-07-16 05:57:43

试试这个:

using System.Drawing;
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);
      for (int y = 0; y < h; y++) {
        byte[] scan = new byte[(w + 7) / 8];
        for (int x = 0; x < w; x++) {
          Color c = img.GetPixel(x, y);
          if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
        }
        Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
      }
      bmp.UnlockBits(data);
      return bmp;
    }

GetPixel() 很慢,您可以使用不安全的字节*来加快速度。

Try this:

using System.Drawing;
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);
      for (int y = 0; y < h; y++) {
        byte[] scan = new byte[(w + 7) / 8];
        for (int x = 0; x < w; x++) {
          Color c = img.GetPixel(x, y);
          if (c.GetBrightness() >= 0.5) scan[x / 8] |= (byte)(0x80 >> (x % 8));
        }
        Marshal.Copy(scan, 0, (IntPtr)((int)data.Scan0 + data.Stride * y), scan.Length);
      }
      bmp.UnlockBits(data);
      return bmp;
    }

GetPixel() is slow, you can speed it up with an unsafe byte*.

掀纱窥君容 2024-07-16 05:57:43

在 Win32 C API 中,创建单色掩码的过程很简单。

  • 创建与源位图一样大的未初始化 1bpp 位图。
  • 将其选择为 DC。
  • 选择源位图放入 DC。
  • 在目标 DC 上设置 BkColor 以匹配源位图的遮罩颜色。
  • 使用 SRC_COPY 将源 BitBlt 到目标。

为了获得加分,通常需要将蒙版位图传输回源位图(使用 SRC_AND)以将那里的蒙版颜色归零。

In the Win32 C API the process to create a mono mask is simple.

  • Create an uninitialzied 1bpp bitmap as big as the source bitmap.
  • Select it into a DC.
  • Select the source bitmap into a DC.
  • SetBkColor on the destination DC to match the mask color of the source bitmap.
  • BitBlt the source onto the destination using SRC_COPY.

For bonus points its then usually desirable to blit the mask back onto the source bitmap (using SRC_AND) to zero out the mask color there.

深府石板幽径 2024-07-16 05:57:43

你是说LockBits吗? Bob Powell 在此处了解了 LockBits ; 这应该提供对 RGB 值的访问,以执行您需要的操作。 您可能还想看看 ColorMatrix,像这样

Do you mean LockBits? Bob Powell has an overview of LockBits here; this should provide access to the RGB values, to do what you need. You might also want to look at ColorMatrix, like so.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文