65.9K
CodeProject is changing. Read more.
Home

Fuzzy DropShadows in GDI+

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.53/5 (32 votes)

Oct 6, 2006

CPOL

2 min read

viewsIcon

89413

downloadIcon

2565

Creating fuzzy drop shadows for GDI+ drawn objects.

Sample Image - FuzzyShadows.jpg

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.