Condividi tramite


Saving images (.bmp, .png, etc) in WPF/Silverlight

I’ve recently added a new feature to Live Geometry that allows users to save the current drawing as a bitmap or a .png file. Just push the save button and pick the desired image format in the Save dialog:

image

Fortunately, both WPF and Silverlight support saving full visual contents of any visual into a file on disk. However the approach is somewhat different.

Saving images in WPF

WPF can save any Visual to an image and it supports several formats out of the box via a concept of Encoders. Here’s a sample for .bmp and .png:

 void SaveToBmp(FrameworkElement visual, string fileName)
{
    var encoder = new BmpBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

void SaveToPng(FrameworkElement visual, string fileName)
{
    var encoder = new PngBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap(
        (int)visual.ActualWidth,
        (int)visual.ActualHeight,
        96,
        96,
        PixelFormats.Pbgra32);
    bitmap.Render(visual);
    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);

    using (var stream = File.Create(fileName))
    {
        encoder.Save(stream);
    }
}

These types are all in System.Windows.Media.Imaging.

Saving images in Silverlight 3

In Silverlight, the encoders don’t come as part of the Silverlight runtime – but fortunately there is a project on CodePlex called ImageTools (https://imagetools.codeplex.com) that provides necessary support. You will need to download the following binaries and add them as references to your Silverlight project:

  • ICSharpCode.SharpZipLib.Silverlight
  • ImageTools
  • ImageTools.IO
  • ImageTools.IO.Png (only if you want .png support)
  • ImageTools.IO.Bmp (only if you want .bmp support)
  • ImageTools.Utils

After that, you can call the ToImage() extension method on any Canvas:

 void SaveAsPng(Canvas canvas, SaveFileDialog dialog)
{
    SaveToImage(canvas, dialog, new PngEncoder());
}

void SaveAsBmp(Canvas canvas, SaveFileDialog dialog)
{
    SaveToImage(canvas, dialog, new BmpEncoder());
}

void SaveToImage(Canvas canvas, SaveFileDialog dialog, IImageEncoder encoder)
{
    using (var stream = dialog.OpenFile())
    {
        var image = canvas.ToImage();
        encoder.Encode(image, stream);
    }
}

Since you can’t write to disk directly in Silverlight, you can pass a SaveFileDialog and use its stream, or you can obtain a stream elsewhere and pass that. The ToImage() extension method does the dirty work that we had to do ourselves in WPF.

Big thanks to https://imagetools.codeplex.com for their awesome library and encoders!

Comments

  • Anonymous
    October 12, 2009
    The comment has been removed

  • Anonymous
    December 09, 2009
    canvas.ToImage(); do not contain defindion ToImage(); Please help me?

  • Anonymous
    January 20, 2010
    canvas.ToImage(); do not contain defindion ToImage(); I m having same issue any help ?

  • Anonymous
    February 07, 2010
    for those with the problems with the extension method. Add this to the top of your page: using ImageTools;

  • Anonymous
    November 22, 2010
    HI i saved image only what i am seen in the View, if my Image is big and scrol bars came that part is not saved.. also more than300*3000 also not able to create image .. if this thing solved it is perfect to use. Thanks

  • Anonymous
    November 22, 2010
    My Email id is muruganas81@gmail.com  pls replay my comment if u need more info  pls ask me

  • Anonymous
    May 31, 2012
    How we can save the image in isolated storage and display in image control with silverlight . Pleas help me . I have an issue I can show the ashx image in silverlight apps but when its xap use in windows .vb apps image is not going to work its not showing  what is issue I could not understand how can I short out this one please hwlp me

  • Anonymous
    May 31, 2012
    How can I download the image like "http://../../Handler.ashx?winnerId=27" and save in local folder in silverlight , I have used so many way but I couldn't get any right solution so that this image display in .net windows application.

  • Anonymous
    July 05, 2012
    if i have a Image instance, not files provided by OpenFileDialog, do you have solutions to save this Image instance to server drives.

  • Anonymous
    November 07, 2013
    Nice one. Cheers.