Silverlight Bitmap Effects
Tuesday, 08 June 2010
Article Index
Silverlight Bitmap Effects
DropShadow and glow
Appying to a bitmap

Banner

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, but 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 WriteableBitmap to render the original bitmap with the effect applied. However to do this wwe need to move the processing of the bitmap into an event handler that is only called when the file has been loaded and is ready to be used.

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

Uri uri = new Uri(@"/test.jpg",
UriKind.Relative);
BitmapImage BMI = new BitmapImage(uri);
BMI.CreateOptions =
BitmapCreateOptions.None;
 

Next we define the ImageOpened event:

BMI.ImageOpened += (object sender1,
          RoutedEventArgs e1) =>
{

Notice that we are using a lambda expression to make the task easier and closure to allow us access to the local variables.

Once the bitmap is loaded the ImageOpened event fires and calls the lambda expression defined.The idea is that we first set up the Image control to display the bitmap with the desired effect:

image1.Effect = new BlurEffect() 
{ Radius = 100 };
image1.Stretch = Stretch.None;
image1.Source = BMI;

Now  create a WriteableBitmap of the same size as the original bitmap and render the Image control to it:

WriteableBitmap WBM = 
new WriteableBitmap(
BMI.PixelWidth, BMI.PixelHeight);
Size sz = new Size(
BMI.PixelWidth, BMI.PixelHeight);
image1.Measure(sz);
image1.Arrange(
new Rect(new Point(0, 0), sz));
WBM.Render(image1, null);
WBM.Invalidate();

Notice the need to use Arrange and Measure on the Image control to make sure that the layout works correctly during the render. We also need to Invalidate the WriteableBitmap to make sure it updates.

Finally we can display the new bitmap in the original Image control:

image1.Effect = null;
image1.Source = WBM; 

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 WriteableBitmap. 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 WriteableBitmap. Notice that in WPF the size of the Rectangle is specified in logical pixels but in Silverlight we use actual pixels.

First we load the bitmap:

Uri uri = new Uri(@"/test.jpg",
UriKind.Relative);
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() 
{ Width = BMI.PixelWidth,
Height = BMI.PixelHeight };
rct.Fill = new ImageBrush()
{ ImageSource = BMI };
rct.Effect = new BlurEffect()
{ Radius = 10 };
 

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

Size sz = new Size(
BMI.PixelWidth,BMI.PixelHeight);
rct.Measure(sz);
rct.Arrange(new Rect(new Point(0,0),sz));
 

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

WriteableBitmap WBM = new 
WriteableBitmap(
BMI.PixelWidth,BMI.PixelHeight);

WBM.Render(rct, null);
WBM.Invalidate();
image1.Source = WBM;

render

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.

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

Banner

<ASIN:1847199763 >

<ASIN:0470534044 >

<ASIN:0470524650 >

<ASIN:1430230185 >

<ASIN:0672333368 >

<ASIN:1430272074 >



Last Updated ( Monday, 26 July 2010 )
 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.