如何使用GDI在运行时创建带有Alpha通道的位图?

3

我正在使用分层窗口,在屏幕上绘制圆角矩形。但是,我想要平滑边缘。我认为需要使用alpha混合。是否有一种使用GDI实现这个的方法?

4个回答

3

使用CreateDIBSection函数创建一个32bpp位图。在BITMAPINFOHEADER中填充信息,使用预乘alpha通道填充alpha通道即可完成。

AlphaBlend是用于实际混合带有alpha通道的32bpp位图的API。


0
你可以使用C#中的BitMap类的LockBits方法来实现这一点(请参见此问题以获取解释)。绝对不要使用GetPixel和SetPixel,因为它们非常慢(即使您只是操作边缘而不是整个位图)。

遗憾的是,我没有使用托管语言。我需要使用原始的Windows API。 - wkf
那是可以做到的,只是不是我来做。=) - MusiGenesis

0

有没有可能使用GDI+代替GDI?它支持抗锯齿和透明度。


1
如果我使用GDI+,我将被困在平面API中,这些API似乎不太友好。虽然如果GDI+能让我的工作更轻松,我会考虑切换到更“类友好”的东西。我会去看看的,谢谢! - wkf
我也遇到了锯齿线的问题,而且我在执行 CImage::AlphaBlend 时使用的是 GDI+。 - sergiol
@sergiol 在那个陈述中没有足够的信息来帮助你。我建议你开一个新问题。 - Mark Ransom

-1

使用GDI调用并没有简单的方式来进行这样的绘图。你所需要的不仅仅是阿尔法混合:你需要反锯齿处理。通常情况下,这需要在更高分辨率下绘制你所需的内容,然后再进行缩放。

我过去解决类似问题的方法是使用一个美术程序,将我想要的任何形状(例如圆角)以黑白方式画大。当我想要绘制它时,我会将黑白位图按比例缩放到所需大小(使用Code Project的缩放类的变体)。这给了我一张灰度图像,我可以将其用作阿尔法通道,然后通过调用Win32函数AlphaBlend或使用DIBSection并手动更改适当的像素来进行阿尔法混合。

另一种方法是分配一个大约比最终结果大四倍的DIBSection,向其中绘制,然后使用上述缩放类将其缩小:从较大的图像进行缩放将产生适当的平滑效果。

如果所有这些听起来都需要花费很多时间:那么确实如此。

编辑:回答这个问题的标题:您可以通过调用CreateDIBSection创建带有Alpha通道的位图。不过,仅仅这样做是不够的,我认为。


今天下午在浏览MSDN时,我偶然发现了CreateDIBSection,它似乎是我缺失的那个部分。我使用吴氏线/圆算法来绘制抗锯齿线条和圆形;只要我可以访问实际的像素数据,我就可以将其设置为任何我想要的。而且你说得对;这确实是一项艰巨的工作! ;p - wkf
听起来你已经基本上完成了。DIB(设备无关位图)部分非常适合图形工作:你可以获得HBITMAP句柄,但也可以访问原始像素数据。 - DavidK
抗锯齿不是“缩小”,而是在对角线或曲线边缘周围添加额外的阴影像素,以使其外观更加平滑。如果您添加的像素具有 alpha 组件(即它们使用 alpha 混合),则效果会好得多。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接