Custom BitmapSource
Custom BitmapSource
Monday, 03 May 2010
Article Index
Custom BitmapSource
Implementing a constructor
Properties
Image control
Advanced BitmapSource

Going further

There are lots of additional jobs that need to be completed to make the test card bitmap class work as a complete BitmapSource but the rest is mostly just implementation of the missing methods, properties and events. What is more interesting is to consider problems that arise in implementing more sophisticated custom BitmapSources.

No encapsulated BitmapSource

First notice that in nearly many case you are going to have to have an encapsulated BitmapSource within your custom class - this is simply the easy way of creating a bitmap that can be presented to the rest of the system. However it isn't essential.

As the only time your custom class interacts with the rest of the system is when it passes on the bits that define the bitmap and because this is a transfer to an array in the correct format you only have to provide a method that generates the bit data. For example, our test card class can return the data stored in the byte array rather than using the encapsulated BitmapSource:

public override void CopyPixels(
Int32Rect sourceRect,
Array pixels,
int stride,
int offset)
{
int start = sourceRect.Y * stride;
Array.Copy(bits,start,
pixels,0,stride);
}

Notice that this assumes that the bits byte array is global and accessible and the CopyPixels method isn't general. It only implements the very minimum needed to copy a single stride side chunk of data starting at (0,y). A more complete solution would have to map the sourceRect to the data stored in the byte array. Not difficult but messy.

For another, extreem example, let's generate random pixel data everytime CopyPixels is called:

public override void CopyPixels(
Int32Rect sourceRect,
Array pixels,
int stride, int offset)
{
Random R = new Random();
R.NextBytes((byte[])pixels);
}

This is particularly simple because all we have to do is fill the pixels array with random numbers - sizes and sourceRectangles are irrelevant! If you try this out you will see a random display

 

random

Random pixels

If you look at the example image you might be puzzled as to why the random pixels form vertical bars? The reason is that the random number generator is reset for each row of the image using a time dependent seed. Each row is transfered so quickly that the time dependent seed generally doesn't change and so you get a repeat of the pseudo random pattern until the seed does change - when you see an occational tearing of the image. If you want a more reaonable random pattern move the random number generator to be global and create it just once with a time dependent seed. 

In all of these examples the CopyPixel method has be written to be specific to the data transfer used by the Image control. There is no promise that all data transfers occur in this way so you have to implement all of the CopyPixel methods and in a completely general way.

Source properties and chaining

Another common requirement is the need to specify a source property.  A source property is simply another BitmapSource instance that you retrieve data from. To do this you make use of the CopyPixels method of choice to transfer the bitmap data in the object specified by the Source to your custom object. In fact you simply implement the mechanism that the Image control uses to get its data.

Once you have the represenation of the bits you can arrange for your custom BitmapSource to pass these on to another BitmapSource derived object via its Source property. In this way a chain of Bitmapped sources can be built up.

For example, without adding a Source property to our custom bitmap it can still be used as the start of a chain:

TestBitmapSource TBS = new 
TestBitmapSource(100, 100);
TransformedBitmap BS = new
TransformedBitmap();
BS.BeginInit();
BS.Transform = new
ScaleTransform(0.5, 2);
BS.Source = TBS;
BS.EndInit();
image1.Source = BS;

transform

A rescaled test card

For more information on how to use transformations see our explorations of the bitmap transform classes.

Asynchronous download

More advanced BitmapSource classes have to cope with the possibility that the bitmap data wont be available immediately. In this case you have little choice but to implement all of the methods and properties provided by classes such as BitmapImage. The basic idea is that you store a source URI in a suitable property and then either get on with loading it or defer until the pixels are actually needed. For example when a client accesses the bitmap data using CopyPixels your custom class has to check that the data is available and block the thread until it is. Of course blocking the UI thread isn't a good idea and in practice you have implement something more sophisticated using a worker thread to download the data while the UI gets on with its task. This rapidly becomes very complicated and difficult to get right.

If possible avoid this task by using the classes provided!

Banner


WPF The Easy 3D Way

WPF provides a full 3D graphics experience without the need to master DirectX. It really is the easy 3D approach.



BitmapSource: WPF Bitmaps

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



Loading Bitmaps: DoEvents and the closure pattern

Sometimes loading a bitmap causes an asynchronous download and you have to wait for it to complete before using it - but how best to wait? The standard solution is to use an event but this breaks what [ ... ]



Inside Dependency Properties

Learn how dependency properties really work by creating a custom dependency property



The bitmap transform classes

WPF bitmaps are immutable but that doesn't mean you can't transform them. Find out about rotation, scaling, changing pixel formatting and how to mangage color profiles.


Other Articles

<ASIN:1430219106>

<ASIN:1430226501>

<ASIN:0735627045>

<ASIN:0470499834>

<ASIN:0672330318>



Last Updated ( Sunday, 02 May 2010 )
 
 
Banner

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