How to paint a shadow?

J

JezB

I can't find a good way to draw a nice shadow behind a rectangular object. I
can of course display a light grey rectangle behind the rectangle, offset by
a few pixels, but this just does not look very professional. Instead I want
a grey shadow that is "blurred" at the edges. I can't prepare an image for
the shadow and paint this - I've tried it, my rectangle can vary in size and
scaling the shadow image again doesn't look good, especially when the shadow
image has to be enlarged.

Does anyone have any good advice on this ? Maybe I need a method in GDI+ to
apply a blur effect, but I can't find one in the documentation.
 
T

Tim Scott

JezB,

There may be other ways, but one technique we've used is to take a page
from web design principles: You could make a stock shadow image, and
slice it into 9 parts. This would give you 4 corners, 2 side pieces, 2
top/bottom edges, and the middle.

The idea is that you then can scale the parts as needed to fill your
shadow area.
You scale horizontally the top and bottom parts, or vertically for the
side parts.

For example (please pardon the horrible ASCII art):
Here is a small shadow block that you draw in a drawing program.

/-\
|*|
\-/

You then slice it into the 9 parts: / \ \ / corners, - - top and bottom
edge, | | left and right edge, and * the middle. You save those in a
resource file or as 9 image files.

At runtime, to draw your shadow behind your rectangular object, you
strech the parts as far as needed to fill behind your rectangle:
/-----\
|*****|
|*****|
\-----/

(I know these are hard to understand, so I will try to update my blog
later on with some real images).

Here we streched the side parts by 5x in one direction, and the middle
5x in both directions. Then you draw your rectangle object on top.
You stretch the image during drawing with Graphics.DrawImage()

If your shadow is symmetrical, then you really only need one corner,
one edge, and maybe the middle. You then rotate the corner and edge
parts 90 degrees each time for the other corners and edges. The middle
is probably one solid color, and you can fill that with
Graphics.FillRectangle()

Drawbacks to this approach are that you can't easily change the shadow
color at runtime; nor change the amount of blur in your shadow. You
could change the "darkness" of the shadow by changing the alpha of the
image before you apply it...


Another approach is to use gradient fills. If you look at the parts we
generated, the edges are just linear gradients. You could draw them
with the LinearGradientBrush. The corners are the hard part, though.
These are quarter-circle sections of a radial gradient fill. There is
no radial gradient fill in GDI+; but you might be able to construct one
with the PathGradientBrush on a circular path, and mask out 3/4 of the
circle that you don't need during drawing. I have never tried this,
however. We have written our own code to do this type of fill (in GDI,
not GDI+, but the effect is the same).

Again, there may be some better ways, but these two approaches have
worked for us in the past. Please check my blog in the next couple of
days, I'll try to get up some images that show how this could be done.

Good luck!

-- Tim Scott
http://geekswithblogs.net/tscott
 
T

Tim Scott

You might also take a look at the Blur effect and Graphics.DrawImage()
method that takes an Effect object in the call. These are in GDI+ (not
..NET's System.Drawing).

http://msdn.microsoft.com/library/d...cpp/GDIPlus/GDIPlusreference/classes/blur.asp

http://msdn.microsoft.com/library/d...ge_Imageimage_RectFsourceRect_MatrixxForm.asp

You could draw a gray rectangle onto a Graphics context for an image,
and then draw that image with the blur effect onto your final Graphics
context.


-- Tim Scott
http://geekswithblogs.net/tscott
 
B

Bob Powell [MVP]

Take a look at how to paint shadows for text effects in the GDI+ FAQ. This
is pretty much the same for shadows for shapes.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.
 
G

Guest

Take a look at the various static methods on
System.Windows.Forms.ControlPaint as well.
 
G

Guest

Take a look at the various static methods of
System.Windows.Forms.ControlPaint as well.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top