简体   繁体   English

如何使用GDI动态创建带alpha通道的位图?

[英]How do I create a bitmap with an alpha channel on the fly using GDI?

I am using layered windows and drawing a rounded rectangle on the screen. 我正在使用分层窗口并在屏幕上绘制一个圆角矩形。 However, I'd like to smooth out the jagged edges. 但是,我想平滑锯齿状的边缘。 I think that I'll need alpha blending for this. 我认为我需要alpha混合。 Is there a way I can do this with GDI? 我有办法用GDI做到这一点吗?

CreateDIBSection. CreateDIBSection。 Fill in the BITMAPINFOHEADER with 32bpp. 用32bpp填写BITMAPINFOHEADER。 Fill in the alpha channel with pre-multiplied alpha and youre good to go. 使用预乘的alpha填充alpha通道,你就可以了。

AlphaBlend is the API to actually blit 32 bpp bitmaps with an aplha channel. AlphaBlend是一个用aplha通道实际上blit 32 bpp位图的API。

You can do this in C# using the LockBits method of the BitMap class (see this question for an explanation). 您可以使用BitMap类的LockBits方法在C#中执行此操作(请参阅此问题以获得解释)。 You definitely don't want to use GetPixel and SetPixel for this, as they are hideously slow (even though you'd just be manipulating the edges and not the entire bitmap). 你绝对不想使用GetPixel和SetPixel,因为它们非常慢(即使你只是操纵边缘而不是整个位图)。

Any chance of using GDI+ instead of GDI? 有没有机会使用GDI +代替GDI? It supports antialiasing and transparency right out of the box. 它开箱即用,支持抗锯齿和透明度。

There isn't an easy way to do such drawing with just GDI calls. 只用GDI调用就没有简单的方法来进行这种绘图。 What you want isn't just alpha blending: you want anti-aliasing. 你想要的不只是alpha混合:你想要抗锯齿。 That usually involves drawing what you want at a larger resolution and then scaling down. 这通常涉及以更大的分辨率绘制您想要的内容,然后缩小。

What I've done in the past for similar problems is to use an art program to draw whatever shape I want (eg a rounded corner) much larger than I needed it in black and white. 我过去对类似问题所做的是使用艺术程序来绘制我想要的任何形状(例如圆角)比我在黑白中所需要的大得多。 When I wanted to draw it I would scale the black and white bitmap to whatever size I wanted (using a variant of a scaling class from Code Project ). 当我想绘制它时,我会将黑白位图缩放到我想要的任何大小(使用Code Project中的缩放类的变体)。 This gives me a grayscale image that I can use as an alpha channel, which I'd then use for alpha blending, either by calling the Win32 function AlphaBlend, or by using a DIBSection and manually changing the appropriate pixels. 这给了我一个灰度图像,我可以用它作为alpha通道,然后通过调用Win32函数AlphaBlend,或者通过使用DIBSection并手动更改相应的像素,我将其用于alpha混合。

Another variation of this approach would be to allocate a DIBSection about four times larger than you wanted the final result, draw into that, and then use the above scaling class to scale it down: the scaling from a larger image will give the appropriate smoothing effect. 这种方法的另一个变体是分配一个大约比你想要的最终结果大四倍的DIBSection,然后使用上面的缩放类来缩小它:从更大的图像缩放将给出适当的平滑效果。

If all this sounds like quite a lot of work: well, it is. 如果所有这些听起来像是很多工作:嗯,确实如此。

EDIT: To answer the title of this question: you can create a bitmap with an alpha channel by calling CreateDIBSection. 编辑:要回答这个问题的标题:你可以通过调用CreateDIBSection创建一个带alpha通道的位图。 That won't on its own do what you want though, I think. 我想,这不会自己做你想做的事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM