Bigger isn’t always better [How to: Resize images without reloading them with WPF]


This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

WpfResizeImageSample.zip

Comments (5)

  1. raulgspan says:

    Hey David, avid reader of your blog, thanks for all the great work. I stumbled upon this post while searching for an efficient way to scale images in WPF and put your code to use, but I’m seeing a small issue. When I execute this code at high frequency, using a RenderTargetBitmap of 850×425 pixels as the ImageSource and scaling down to 90×45, ~2MB of RAM are consumed each time resizedImage.Render(drawingVisual) is called. So for example if I execute this 5 times in a row quickly, ~8-10MB of RAM is consumed. This is definitely later garbage collected so it’s not like there’s a leak or anything, but trampling through that much RAM can’t be very efficient (I need to execute this scaling about once per second). I was wondering if you’d observed this as well and if you had any advice on dealing with it?

    Thanks, Russell Greenspan, Tutor.com.

  2. Delay says:

    Russell,

    Thanks for the kind words! I’m not sure I understand your scenario, but if you’re doing all this work to replace the *same* image every time (kind of like a flip book?), then maybe it’s not worth creating the smaller version of the image anyway since it’s just going to be discarded 1 second later anyway. If that’s the case, I’d say just let WPF render the big image small and then you can save on this work and extra memory allocation. Alternatively, if you *know* the dimensions of the source image, you can set both DecodePixelWidth and DecodePixelHeight because you can do the math yourself to maintain the aspect ratio. This is probably the ideal if it’s possible. :)

    Hope this helps!

  3. raulgspan says:

    Thanks for the quick response.

    Bit of a longer story, but unfortunately I have no choice but to continuously re-do the work (since I need to create a png of each altered thumbnail). I’ve just started to work through it, but so far what’s working much better for me is assigning the FrameworkElement I need to thumbnail to the VisualBrush of a thumbnail-sized Rectangle (instead of using RenderTargetBitmap), then using a RenderTargetBitmap to render the Rectangle. The code actually ends up being quite a bit simpler… I avoid using the 850×425 RenderTargetBitmap AND the CreateResizedImage() code and instead just work with a RenderTargetBitmap of the 90×45 Rectangle.

    Thanks again for your help!

  4. Delay says:

    Russell,

    Nicely done! I’ll be sure to keep that trick in mind. :) Thanks for sharing it!