3

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. Is there a way I can do this with GDI?

wkf
  • 842
  • 9
  • 17

4 Answers4

3

CreateDIBSection. Fill in the BITMAPINFOHEADER with 32bpp. Fill in the alpha channel with pre-multiplied alpha and youre good to go.

AlphaBlend is the API to actually blit 32 bpp bitmaps with an aplha channel.

Chris Becke
  • 34,244
  • 12
  • 79
  • 148
0

You can do this in C# using the LockBits method of the BitMap class (see this question for an explanation). 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).

Community
  • 1
  • 1
MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
0

Any chance of using GDI+ instead of GDI? It supports antialiasing and transparency right out of the box.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 1
    If I did use GDI+, I'd be stuck with the flat APIs, which seem less friendly to use. Though if GDI+ made my job easier, I'd be tempted to switch to something more 'class friendly'. I'll check this out; thanks! – wkf Jul 24 '09 at 22:07
  • I have the problem of jagged lines also and I am using GDI+ when I am doing a `CImage::AlphaBlend` – sergiol Nov 09 '16 at 18:18
  • @sergiol there's not nearly enough information in that statement to help you out. I'd suggest opening a new question. – Mark Ransom Nov 09 '16 at 19:34
-1

There isn't an easy way to do such drawing with just GDI calls. What you want isn't just alpha blending: you want anti-aliasing. 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 (e.g. 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). 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.

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.

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. That won't on its own do what you want though, I think.

DavidK
  • 3,929
  • 1
  • 19
  • 26
  • I stumbled across CreateDIBSection while scouring MSDN this afternoon, and it seems to be piece I was missing. I use Wu's line/circle algorithms for drawing anti-aliased lines and circles; as long as I have access to the actual pixel data, I can set it to whatever I want. And you're right; it is turning out to be a lot of work! ;p – wkf Jul 24 '09 at 22:06
  • It sounds like you're basically there. DIB sections are great for graphics work: you get a HBITMAP handle, but you can access the raw pixel data too. – DavidK Jul 25 '09 at 09:55
  • Anti-aliasing is not "scaling down", it's adding extra shading pixels around diagonal, or curved edges to give it a smoother appearance. This works MUCH better if your added pixels have an alpha component (i.e. they use alpha blending). – Eric Jul 25 '09 at 13:46