【问题标题】:How do I create a bitmap with an alpha channel on the fly using GDI?如何使用 GDI 即时创建具有 Alpha 通道的位图?
【发布时间】:2010-11-13 19:12:54
【问题描述】:

我正在使用分层窗口并在屏幕上绘制一个圆角矩形。但是,我想平滑锯齿状的边缘。我认为我需要为此进行 alpha 混合。有没有办法用 GDI 做到这一点?

【问题讨论】:

    标签: windows winapi graphics bitmap gdi


    【解决方案1】:

    创建DIBSection。用 32bpp 填写 BITMAPINFOHEADER。用预乘的 Alpha 填充 Alpha 通道,一切顺利。

    AlphaBlend 是使用 aplha 通道实际 blit 32 bpp 位图的 API。

    【讨论】:

      【解决方案2】:

      您可以在 C# 中使用 BitMap 类的 LockBits 方法执行此操作(有关说明,请参阅 this question)。您绝对不想为此使用 GetPixel 和 SetPixel,因为它们非常慢(即使您只是在处理边缘而不是整个位图)。

      【讨论】:

      • 遗憾的是我没有使用托管语言。我需要使用普通的 Windows API。
      • 这是可行的,只是不是我。 =)
      【解决方案3】:

      是否有机会使用GDI+ 代替 GDI?它支持开箱即用的抗锯齿和透明度。

      【讨论】:

      • 如果我确实使用了 GDI+,我会被平面 API 卡住,这些 API 使用起来似乎不太友好。虽然如果 GDI+ 让我的工作更轻松,我会很想改用更“类友好”的东西。我会检查一下;谢谢!
      • 我也有锯齿线的问题,我在做CImage::AlphaBlend时使用GDI+
      • @sergiol 该声明中几乎没有足够的信息来帮助您。我建议提出一个新问题。
      【解决方案4】:

      仅使用 GDI 调用来进行这种绘制并不容易。您想要的不仅仅是 Alpha 混合:您还想要抗锯齿。这通常涉及以较大的分辨率绘制您想要的内容,然后按比例缩小。

      我过去针对类似问题所做的是使用艺术程序绘制我想要的任何形状(例如圆角),它比我需要的黑白大得多。当我想绘制它时,我会将黑白位图缩放到我想要的任何大小(使用scaling class from Code Project 的变体)。这为我提供了一个灰度图像,我可以将其用作 Alpha 通道,然后我将通过调用 Win32 函数 AlphaBlend 或通过使用 DIBSection 并手动更改适当的像素,将其用于 Alpha 混合。

      这种方法的另一种变体是分配一个比您想要的最终结果大四倍的 DIBSection,将其绘制进去,然后使用上面的缩放类来缩小它:从更大的图像缩放将给出适当的平滑效果。

      如果这一切听起来工作量很大:嗯,确实如此。

      编辑:回答这个问题的标题:您可以通过调用 CreateDIBSection 创建一个带有 alpha 通道的位图。不过,我认为,它本身并不能满足您的需求。

      【讨论】:

      • 我今天下午在搜索 MSDN 时偶然发现了 CreateDIBSection,它似乎是我遗漏的部分。我使用 Wu 的线/圆算法来绘制抗锯齿线和圆;只要我可以访问实际的像素数据,我就可以将其设置为任何我想要的。你是对的;原来是很多工作! ;p
      • 听起来你基本上就在那里。 DIB 部分非常适合图形工作:您可以获得 HBITMAP 句柄,但您也可以访问原始像素数据。
      • 抗锯齿不是“缩小”,而是在对角线或弯曲边缘周围添加额外的阴影像素,使其外观更平滑。如果您添加的像素具有 alpha 分量(即它们使用 alpha 混合),这会更好。
      猜你喜欢
      • 2012-11-22
      • 2012-03-16
      • 2013-06-02
      • 2011-08-21
      • 2016-05-07
      • 2013-07-22
      • 2011-02-06
      • 2012-03-06
      • 2010-09-23
      相关资源
      最近更新 更多