Bitmap Effects
Monday, 24 May 2010
Article Index
Bitmap Effects
DropShadow and glow
Appying to a bitmap


Applying an effect to a bitmap

You might think that we have already covered applying an effect to a bitmap - but no.




The effects might be called bitmap effects, and indeed they are as they work with pixels, the pixels are the result of rendering a graphic - usually a vector graphic. 

A bitmap is a graphic but it is only rendered when displayed on the screen. As already explained, when we apply an effect to an image control it is the entire control which the effect applies to i.e the pixels that result from rendering the control and its contents.

Suppose, however, we want to apply the effect to a bitmap to produce a new bitmap which is then displayed in an image control say?

You can do this but it isn't quite as simple as it seems. What you have to do is to use a RenderTargetBitmap to render the original bitmap with the effect applied. As explained in another article, using RenderTargetBitmap isn't always easy to use.

First let's just use the Image control and basic set up in the previous examples. That is first load the bitmap into the Image control:

Uri uri = new Uri(
Directory.GetCurrentDirectory() +
@"\test.jpg", UriKind.Absolute);
BitmapImage bmi =
new BitmapImage(uri);
image1.Stretch = Stretch.None;
image1.Source = bmi;

Notice that the image control doesn't stretch the bitmap to fit whereas in other screen dumps it did.

Now we apply the effect, create a RenderTargetBitmap of the same size as the original bitmap and render the Image control to it:

image1.Effect = new 
new Rect(0,0,
RenderTargetBitmap rtbmp = new

Notice the need to use Arrange on the Image control to make sure that the WPF layout works correctly during the render. Finally we can display the new bitmap in the original Image control:

image1.Effect = null;
image1.Source = rtbmp;

Notice that we only get the portion of the bitmap that actually displayed in the Image control. This is the basic problem with this approach of using an Image control, i.e. the original bitmap is cropped to fit the Image control and this is what is rendered into the RenderTargetBitmap. If you make the Image control the same size as the bitmap and then render it then you do get the entire bitmap with the effect applied. However there is a better method which doesn't involve displaying the original bitmap at all.

What we can do is create a Rectangle shape with the bitmap as a Fill. Then we can render the Rectangle to the RenderTargetBitmap. This sounds simple but the tricky bit is that the Rectangle is sized in terms of logical pixels, i.e. assuming 96 pixels per inch, so we have to be careful to use the bitmap width and height not its pixel width and height to set the size of the rectangle.

First we load the bitmap:

Uri uri = new Uri(
Directory.GetCurrentDirectory() +
@"\test.jpg", UriKind.Absolute);

BitmapImage bmi = new BitmapImage(uri);

Next we create the Rectangle shape, set its Fill to be a Brush created from the bitmap and set the desired effect:

Rectangle rct = new Rectangle();
rct.Fill = new ImageBrush(bmi);
rct.Effect= new

Next we set the size of the Rectangle using the WPF layout system:

Size sz=new Size(bmi.Width,
rct.Arrange(new Rect(sz));

Finally we render the Rectangle to the RenderTargetBitmap and display the result:

RenderTargetBitmap rtbmp = new 
image1.Source = rtbmp;


A bitmap with an effect applied - notice that the edges of the Image control are sharp as the effect is applied to the bitmap not the control.

Notice that applying a bitmap effect to a bitmap is slower than applying it to a "live" rendered graphic such as a Button or an Image control. The reason is that pixels have to be transferred in both directions from video memory. However if you apply a bitmap effect to a bitmap then it only has to be done once and the bitmap can be reused without reapplying the effect.

In most cases using the GPU to render the image as needed is likely to be faster.

Now that you have mastered the built-in bitmap effects it's time to move on to custom effects.


Drawing Bitmaps – DrawingImage and DrawingVisual


WPF provides multiple ways to convert vector drawings to bitmaps. Find out how DrawingImage and DrawingVisual work and when to use which. On the way we look at how to create 2D vector drawings.

BitmapSource: WPF Bitmaps

Although bitmap graphics are not a main focus of WPF it does offer some useful facilities


WriteableBitmap gives you a bitmap object that you can modify dynamically - but exactly how to do this isn't always obvious.

Bitmap Coding and Metatdata in WPF

Having looked at working with raw pixel data we turn our attention to formattted image files and how to code and decode both the pixel data and the meta data they contain.


Custom Bitmap Effects - HLSL

In the article Custom Bitmap Effects - Getting started we discovered how to work with HLSL in WPF. Now we are in a position to write more sophisticated shaders and  this means learning some more  [ ... ]

Other Articles






Last Updated ( Saturday, 22 May 2010 )