Description
The WriteableBitmapEx library is a collection of extension methods for Silverlight's
WriteableBitmap. The WriteableBitmap class that was added in Silverlight 3, allows the direct manipulation of a bitmap and could be used to generate fast procedural images by drawing directly to a bitmap. The WriteableBitmap API is very minimalistic and there's only the raw
Pixels array for such operations. The WriteableBitmapEx library tries to compensate that with extensions methods that are easy to use like built in methods and offer
GDI+ like functionality. The library extends the WriteableBitmap class with elementary and fast (2D drawing) functionality, conversion methods and functions to combine (blit) WriteableBitmaps.
The extension methods are grouped into different CS files with a partial class. It is possible to include just a few methods by using the specific source CS files directly or all extension methods through the built library assembly.
See the
Issue Tracker for a list of features that will be added in the future.
Features
GDI+ like drawing functionality for the WriteableBitmap.
Support for desktop and Windows Phone Silverlight.
- Base
- Support for the Color structure (alpha premultiplication will be performed)
- Also overloads for faster int32 as color (assumed to be already alpha premultiplied)
- SetPixel method with various overloads
- GetPixel method to get the pixel color at a specified x, y coordinate
- Fast Clear methods
- Fast Clone method to copy a WriteableBitmap
- ForEach method to apply a given function to all pixels of the bitmap
- Transformation
- Crop method to extract a defined region
- Resize method with support for bilinear interpolation and nearest neighbor
- Shapes
- Fast line drawing algorithms
- Ellipse, polyline, quad, rectangle and triangle
- Cubic Beziér, Cardinal spline and closed curves
- Filled shapes
- Fast ellipse and rectangle fill method
- Polygon, triangle and quad
- Beziér and Cardinal spline curves
- Blitting
- Different blend modes including alpha, additive, subtractive, multiply, mask and none
- Optimized fast path for non blended blitting
- Conversion
- Convert a WriteableBitmap to a byte array
- Create a WriteableBitmap from a byte array
- Create a WriteableBitmap easily from the application resource
- Write a WriteableBitmap as a TGA image to a stream
Live samples
Samples that come with the WriteableBitmapEx source code in action:
- The Shapes sample includes various scenarios where different shapes are drawn. By default a little demo is shown called "Breathing Flower". Basically different sized circles rotating around a center ring are generated. The sample also contains a static page showing some of the possible shapes.
- The Fill sample starts with a demo that animates the Cardinal spline's tension of the FillCurveClosed method, plus some random animated filled ellipses. The sample also contains a static page showing some of the possible filled shapes.
- The Curve sample demonstrates the Beziér and Cardinal spline methods. The sample starts with a demo animation that uses the Cardinal spline DrawCurve method to draw an artificial plant that grows procedurally. The other part of the sample is interactive and allows to draw and manipulate Beziér and Cardinal splines with the mouse. See this blog post for further information.
- The Blit sample combines WriteableBitmaps and shows a neat particle effect.
Video of the
Windows Phone Interactive Curve Sample.
External resources:
Adam Kinney made a
great sample that uses the WriteableBitmapEx library to dynamically apply a torn weathered effect to a photo.
Performance!
The WriteableBitmapEx methods are much faster than the Silverlight
Shape subclasses. For example, the WriteableBitmapEx line drawing approach is more than 20-30 times faster as the Silverlight
Line element. So if a lot of shapes need to be drawn and anti-aliasing or other SIlverlight Shape properties are not needed, the WriteableBitmapEx methods are the right choice.
Easy to use!
// Initialize the WriteableBitmap with size 512x512 and set it as source of an Image control
WriteableBitmap writeableBmp = new WriteableBitmap(512, 512);
ImageControl.Source = writeableBmp;
// Load an image from the calling Assembly's resources only by passing the relative path
writeableBmp = new WriteableBitmap(0, 0).FromResource("Data/flower2.png");
// Clear the WriteableBitmap with white color
writeableBmp.Clear(Colors.White);
// Set the pixel at P(10, 13) to black
writeableBmp.SetPixel(10, 13, Colors.Black);
// Get the color of the pixel at P(30, 43)
Color color = writeableBmp.GetPixel(30, 43);
// Green line from P1(1, 2) to P2(30, 40)
writeableBmp.DrawLine(1, 2, 30, 40, Colors.Green);
// Line from P1(1, 2) to P2(30, 40) using the fastest draw line method with the color as integer
int[] pixels = writeableBmp.Pixels;
int w = writeableBmp.PixelWidth;
int h = writeableBmp.PixelHeight;
WriteableBitmapExtensions.DrawLine(pixels, w, h, 1, 2, 30, 40, myIntColor);
// Black triangle with the points P1(10, 5), P2(20, 40) and P3(30, 10)
writeableBmp.DrawTriangle(10, 5, 20, 40, 30, 10, Colors.Black);
// Red rectangle from the point P1(2, 4) that is 10px wide and 6px high
writeableBmp.DrawRectangle(2, 4, 12, 10, Colors.Red);
// Filled blue ellipse with the center point P1(2, 2) that is 8px wide and 5px high
writeableBmp.FillEllipseCentered(2, 2, 8, 5, Colors.Blue);
// Closed green polyline with P1(10, 5), P2(20, 40), P3(30, 30) and P4(7, 8)
int[] p = new int[] { 10, 5, 20, 40, 30, 30, 7, 8, 10, 5 };
writeableBmp.DrawPolyline(p, Colors.Green);
// Cubic Beziér curve from P1(5, 5) to P4(20, 7) with the control points P2(10, 15) and P3(15, 0)
writeableBmp.DrawBezier(5, 5, 10, 15, 15, 0, 20, 7, Colors.Purple);
// Cardinal spline through the points P1(10, 5), P2(20, 40) and P3(30, 30) with a tension of 0.5
int[] pts = new int[] { 10, 5, 20, 40, 30, 30};
writeableBmp.DrawCurve(pts, 0.5, Colors.Yellow);
// A filled Cardinal spline through the points P1(10, 5), P2(20, 40) and P3(30, 30) with a tension of 0.5
writeableBmp.FillCurveClosed(pts, 0.5, Colors.Green);
// Blit a bitmap using the additive blend mode at P1(10, 10)
writeableBmp.Blit(new Point(10, 10), bitmap, sourceRect, Colors.White, WriteableBitmapExtensions.BlendMode.Additive);
// Override all pixels with a function that changes the color based on the coordinate
writeableBmp.ForEach((x, y, color) => Color.FromArgb(color.A, (byte)(color.R / 2), (byte)(x * y), 100));
// Present the WriteableBitmap!
writeableBmp.Invalidate();
// Take snapshot
var clone = writeableBmp.Clone();
// Save to a TGA image stream (file for example)
writeableBmp.WriteTga(stream);
// Crops the WriteableBitmap to a region starting at P1(5, 8) and 10px wide and 10px high
var cropped = writeableBmp.Crop(5, 8, 10, 10);
// Resizes the WriteableBitmap to 200px wide and 300px high using a bilinear interpolation method
var resized = writeableBmp.Resize(200, 300, WriteableBitmapExtensions.Interpolation.Bilinear);
Additional Information
The WriteableBitmapEx library has its origin in several blog posts that also describe the implemenation and usage of some aspects in detail. The blog posts might be seen as the documentation.
WriteableBitmap Extension Methods introduced the SetPixel methods.
Drawing Lines - Silverlight WriteableBitmap Extensions II provided the DrawLine methods.
Drawing Shapes - Silverlight WriteableBitmap Extensions III brought the shape functionality (ellipse, polyline, quad, rectangle, triangle).
Convert, Encode And Decode Silverlight WriteableBitmap Data came with the byte array conversion methods and hows how to encode / decode a WriteableBitmap to JPEG.
Blitting and Blending with Silverlight’s WriteableBitmap provided the Blit functions.
WriteableBitmapEx - WriteableBitmap extensions now on CodePlex announced this project.
Quick and Dirty Output of WriteableBitmap as TGA Image provided the original TgaWrite function.
Rounder, Faster, Better - WriteableBitmapEx 0.9.0.0 announced version 0.9.0.0 and gives some further information about the curve sample.
Let it ring - WriteableBitmapEx for Windows Phone introtuced the WriteableBitmapEx version for the Windows Phone and a sample.
Filled To The Bursting Point - WriteableBitmapEx 0.9.5.0 announced version 0.9.5.0, has some information about the new Fill methods and comes with a nice sample.
Support it

Credits
Bill Reiss wrote the Blit methods.
Nikola Mihaylov (Nokola) made some optimizations on the DrawLine and DrawRectangle methods and provided the original TgaWrite function.
Adam Kinney added some Blending modes to the Blit method.
Colin Eberhardt contributed the ForEach method.
René Schule wrote all the rest and coordinates this project.