Silverlight 3 introduces the WriteableBitmap class and with it, the ability to crop an image programmatically on the client!
All you need to do is create a new instance of the WritableBitmap class as your destination (supplying the dimensions in the constructor). Then create or acquire another instance of the WriteableBitmap class fully loaded with an image (among other ways, you can do this by creating a BitmapSource object from a stream via .SetSource and passing that BitmapSource instance into the constructor of a new WriteableBitmap)
Once you have your source and destination WriteableBitmap classes, just retrieve one pixel at a time from the source instance and set that pixel on a destination instance. The pixels are stored in a property on the object call Pixels which is a 1 dimensional array. Geting the index of a given pixel in an array is simple: index = x + y * width.
In my first pass, I just looped thru pixel by pixel. This was fast but not as fast as using Array.Copy (almost twice as fast)…
private static WriteableBitmap CropImage(WriteableBitmap Source, int XOffset, int YOffset, int Width, int Height)
{
int SourceWidth = Source.PixelWidth;
WriteableBitmap Result = new WriteableBitmap(Width, Height);
for (int y = 0; y <= Height – 1; y++)
{
int SourceIndex = XOffset + (YOffset + y) * SourceWidth;
int DestIndex = y * Width;
Array.Copy(Source.Pixels, SourceIndex, Result.Pixels, DestIndex, Width);
}
return Result;
}
The result (a WriteableBitmap) can then simply be used as the source of an Image control to display your cropped image.
Note: WriteableBitmap.PixelWidth is expensive. Be sure to call it only once if possible.
Possible Improvement: Had the source width and destination width been the same I could have done it in a single call to Array.Copy and presumably made it even faster.
It’s high time that web developers are able to do complicated tasks on the client and not forced to use the server just because the client-side platform doesn’t support it. We’re still not all the way there yet but Silverlight gets us a lot closer than anything before it.