Fuzzy DropShadows in GDI+






4.53/5 (32 votes)
Creating fuzzy drop shadows for GDI+ drawn objects.
Introduction
I develop a flow charting software for the company I work for and I am always looking for a way to spruce up the application. After getting the nitty gritty down in the application, I turned to the little stuff that users will look at or use and think, awe that's nice. So when it came down to the look of the flow charting object, I wanted a drop shadow to show some depth to the drawing canvas. I searched around and everything that I found on the internet was using an image and skewing or stretching it and drawing it under the object to give it a shadow. So I started drawing the shadow for the object with a transparent color, but there was the problem. It looked ok but the edges were way too sharp, that's when I came up with this solution. Hope you like it and use it - Larry
Overview
Here, I am going to show you a method that I found for making Drop Shadows for GDI+ drawn Shapes that have fuzzy edges. First, we need to set the distance that the shadow should be drawn from the shape. In this example I use a NumericUpDown
control so that we can change this distance and see what distance looks best.
// set the shadow distance
// since we are going back and up minus the value from zero
// this will put the shadow down and to the right of the Shape
_ShadowDistance = 0f - (float)nmDistance.Value;
// force a redraw of the canvas
picCanvas.Invalidate();
Now that we have setup the distance let's get to the drawing. Here, I will not go over what was done to draw the object, only the shadow. So at this point, we have a GraphicsPath()
that has been created to draw our rounded rectangle. So now, we need to create the drop shadow and this is how it's done.
// this is where we create the shadow effect, so we will use a
// pathgradientbursh and assign our GraphicsPath that we created of a
// Rounded Rectangle
using(PathGradientBrush _Brush = new PathGradientBrush(_Path))
{
// set the wrapmode so that the colors will layer themselves
// from the outer edge in
_Brush.WrapMode = WrapMode.Clamp;
// Create a color blend to manage our colors and positions and
// since we need 3 colors set the default length to 3
ColorBlend _ColorBlend = new ColorBlend(3);
// here is the important part of the shadow making process, remember
// the clamp mode on the colorblend object layers the colors from
// the outside to the center so we want our transparent color first
// followed by the actual shadow color. Set the shadow color to a
// slightly transparent DimGray, I find that it works best.|
_ColorBlend.Colors = new Color[]{Color.Transparent,
Color.FromArgb(180, Color.DimGray),
Color.FromArgb(180, Color.DimGray)};
// our color blend will control the distance of each color layer
// we want to set our transparent color to 0 indicating that the
// transparent color should be the outer most color drawn, then
// our Dimgray color at about 10% of the distance from the edge
_ColorBlend.Positions = new float[]{0f, .1f, 1f};
// assign the color blend to the pathgradientbrush
_Brush.InterpolationColors = _ColorBlend;
// fill the shadow with our pathgradientbrush
e.Graphics.FillPath(_Brush, _Path);
}
It's very simple to do but provides a much better presentation of a shadow then just drawing with a slightly transparent brush. I hope that this helps somebody out there.