Today I read a blog on http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx which introduces a new way to resize image with WPF. This new method does not use GDI+ (Microsoft Windows GDI+ is the portion of the Windows XP operating system or Windows Server 2003 operating system that provides two-dimensional vector graphics, imaging, and typography.) but it uses WPF library for resizing images very fast. You can read more details about this method in that blog. In the code below, I would like to summarize and explain a little how it works.
The main concept, that we will read all bytes of image, read the first frame of image and use class TransformedBitmap to create a new bitmap frame with the specific scale transform. In the code snippet below shows how the process runs. So that code below works we need to add reference to following assemblies: PresentationCore and WindowsBase.
static void Main(string args)
string strFileName = "Marshimaro.jpg";
string strThumbnail = "MarshimaroThumb.png";
byte baSource = File.ReadAllBytes(strFileName);
using (Stream streamPhoto = new MemoryStream(baSource))
BitmapFrame bfPhoto = ReadBitmapFrame(streamPhoto);
int nThumbnailSize = 200, nWidth, nHeight;
if (bfPhoto.Width > bfPhoto.Height)
nWidth = nThumbnailSize;
nHeight = (int)(bfPhoto.Height * nThumbnailSize / bfPhoto.Width);
nHeight = nThumbnailSize;
nWidth = (int)(bfPhoto.Width * nThumbnailSize / bfPhoto.Height);
BitmapFrame bfResize = FastResize(bfPhoto, nWidth, nHeight);
byte baResize = ToByteArray(bfResize);
File.WriteAllBytes(@"Thumbnails\" + Path.GetFileNameWithoutExtension(strThumbnail) + ".png", baResize);
BitmapFrame represents image data returned by a decoder and accepted by encoders. You can see in the function ReadBitmapFrame how we can use BitmapDecoder to decode stream data of image and get the first bitmap frame.
The core of complete code is the class TransformedBitmap which supports only orthogonal transforms such as rotation transforms of 90° increments and scale transforms. In FastResize function, we apply ScaleTransform to resize image as following.
private static BitmapFrame FastResize(BitmapFrame bfPhoto, int nWidth, int nHeight)
TransformedBitmap tbBitmap = new TransformedBitmap(bfPhoto, new ScaleTransform(nWidth / bfPhoto.Width, nHeight / bfPhoto.Height, 0, 0));
private static byte ToByteArray(BitmapFrame bfResize)
using (MemoryStream msStream = new MemoryStream())
PngBitmapEncoder pbdDecoder = new PngBitmapEncoder();
private static BitmapFrame ReadBitmapFrame(Stream streamPhoto)
BitmapDecoder bdDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
You can parse the code into class and use it everywhere. The complete code can be downloaded here “WPF Fast image resize”
UPDATE 11.03.2010 : Insert (using Stream) to prevent memory leak.