tags:

views:

681

answers:

4

As part of a UI .net library I need to create corner PNG images to align to the corners of a DIV in order to give it rounded corners.

I thought I could create a dynamic corner by doing the following:

  • Create a bitmap (Let's say 25 x 25)
  • Fill the background Green (The colour outside of the DIV we are creating these for)
  • Call FillEllipse() and create a 50 x 50 circle, with 25% of it overlapping into the 25 x 25 bitmap
  • Finally call DrawEllipse() with the same co-ordinates to draw the border

This works well and creates a corner image.

The problem is that I want to colour called by FillEllipse() to be Color.Transparent. This is so the DIV can have a background colour assigned via a style.

However because the FillEllpise() is creating a transparent circle over a coloured background, nothing will appear.

In in summary: How can I punch out a transparent hole?

I thought ExcludeClip() would help, but that only seems to deal with Recentangles.

+2  A: 

This works:

Dim bmp As New Bitmap(25, 25)

Using g As Graphics = Graphics.FromImage(bmp)
    g.Clear(Color.Transparent)  'This is the key point'
    g.FillEllipse(Brushes.Red, New Rectangle(0, 0, 50, 50))
    g.DrawEllipse(Pens.Black, New Rectangle(0, 0, 50, 50))
End Using

bmp.Save("C:\a\out.png", Imaging.ImageFormat.Png)

EDIT: damn, miss read the question, give me a second to change the code...

EDIT2: Done, the part you need is the graphics path:

Dim bmp As New Bitmap(25, 25)

Using g As Graphics = Graphics.FromImage(bmp)

    Dim gp As New GraphicsPath

    gp.AddLine(0, 0, 25, 0)
    gp.AddArc(New Rectangle(0, 0, 50, 50), -90, -90)
    gp.AddLine(0, 25, 0, 0)


    g.Clear(Color.Transparent)

    g.FillPath(Brushes.Red, gp)
    g.DrawPath(Pens.Black, gp)

End Using

bmp.Save("C:\a\out.png", Imaging.ImageFormat.Png)
Pondidum
I believe that is the inverse of what the OP wants - the outside would be transparent but the inside would not.
samjudson
yep, just added some more code :)
Pondidum
An answer for both ways, very good ;)Thanks for your answer Andy
Peter Bridger
A: 

Your best bet might be to call MakeTransparent on the resulting Bitmap to 'punch' out whatever you drew with the FillEllipse.

samjudson
+1  A: 

You could draw the inverse, using a path.

This sample code draws a transparent quarter circle on black background:

  graphics.SmoothingMode = SmoothingMode.HighQuality;
  var path = new GraphicsPath();
  int radius = 30;
  path.AddArc(-radius, -radius, radius * 2, radius * 2, 0, 90);
  path.AddLine(0, radius, -radius, radius * 2);
  path.AddLine(-radius, radius * 2, radius * 2, radius * 2);
  path.AddLine(radius * 2, radius * 2, radius * 2, 0);
  path.AddLine(radius*2, 0, radius, -radius);
  path.CloseFigure();
  graphics.FillPath(Brushes.Black, path);

If instead of a black background you want a bitmap background, then use the path to clip the drawing of the bitmap rather than to fill an area with a solid color.

mackenir
That seems like a lot of paths added for 3 lines...
Pondidum
Thankc MacKenir, I've given Andy the answer as the code is simpler.
Peter Bridger
Yes, I'd never used GraphicsPath before so it could probably be cleaner.
mackenir
A: 

Maybe try it the other way round? Make the background transparent, draw the border, and then fill the corner with green?

Vilx-