Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Resizing images in Silverlight 3 using WriteableBitmap

Tags:

This is my first day with Silverlight. I’m trying to prototype an application which (among other functions) should be able to resize user supplied images. It should be able to handle and display several resized images at once. The most obviously approaches I've tried seem to "leak" memory in the sense that the original bitmaps are still being referenced in some way which causes Silverlight to allocate hundreds of megabytes of memory after a while. I just want to be able to load the images one by one, resize them and keep the small versions.

To be precise, I've tried the following:

  • Creating a list of System.Windows.Controls.Image's (and scaling them). I'm not surprised that this has not worked.

  • Creating a list of rectangles filled by image brushes. I'm not surprised either.

  • Rendering the bitmaps into System.Windows.Media.Imaging.WriteableBitmap. I expected this to perform well; I assumed that the bitmaps are really just drawn directly and not referenced in any way. However, the memory consumption indicated otherwise.

Here is a snippet of the relevant piece of code:

// create image source
Stream stream = file.OpenRead();
BitmapImage bmpImg = new BitmapImage();
bmpImg.SetSource(stream);
stream.Close();

// create temporary image from it
Image tmpImg = new Image();
tmpImg.Source = bmpImg;

// this is required by WriteableBitmap 
tmpImg.Measure(new Size(100, 100));
tmpImg.Arrange(new Rect(0, 0, 100, 100));

// prepare scaling to 100x100
ScaleTransform scaleTrans = new ScaleTransform();
double scale = (double)100 / (double)Math.Max(bmpImg.PixelHeight, bmpImg.PixelWidth);
scaleTrans.CenterX = 0;
scaleTrans.CenterY = 0;
scaleTrans.ScaleX = scale;
scaleTrans.ScaleY = scale;

// render
WriteableBitmap writeableBitmap = new WriteableBitmap(100, 100);
writeableBitmap.Render(tmpImg, scaleTrans);
writeableBitmap.Invalidate();

// final image
Image img = new Image();
img.Source = writeableBitmap;

I hope I'm not missing anything silly, but it looks to OK to me and does the right thing (except the memory problem). Please also bear in mind that code quality is not supposed to be a production quality; it’s just a quick and dirty prototype.

I noticed that I’m not alone; I found questions related to image manipulation in Silverlight. I’m also aware of the fact that I could use some third party library, do processing on the server or write something even myself, but I’m surprised that Silverlight does not offer any basic image manipulation functions. It does not seem to be an uncommon requirement given where Silverlight positions itself.

like image 673
Jan Zich Avatar asked Aug 04 '09 22:08

Jan Zich


1 Answers

Have you looked at the WriteableBitmapEx project? It's an open source project with a tonne of extension methods for the WriteableBitmap class. Here's how you resize:

BitmapImage image = new BitmapImage();
image.SetSource(dialog.File.OpenRead());

WriteableBitmap bitmap = new WriteableBitmap(image);
WriteableBitmap resizedBitmap = bitmap.Resize(500, 500, WriteableBitmapExtensions.Interpolation.Bilinear);

// For uploading
byte[] data = resizedBitmap.ToByteArray();
like image 84
Chris S Avatar answered Oct 13 '22 10:10

Chris S