Canvas save to PNG

Jul 17, 2009 at 8:44 PM

Sorry tried to use your library to save a Canvas as PNG but didn't manage to get it working, I think I'm doing wrong (trying getBytes...), do you have any sample available or some hints / steps?

Thanks

  Braulio

Jul 18, 2009 at 8:33 AM
It's not that hard...
            WriteableBitmap bitmap = new WriteableBitmap(canvasToExport, new TranslateTransform());
            bitmap.Invalidate();

            //read every color of each pixel of writablebitmap into ImageTools-Image
            ImageTools.Image imageData = new ImageTools.Image(bitmap.PixelWidth, bitmap.PixelHeight);
            try
            {
                for (int y = 0; y < bitmap.PixelHeight; ++y)
                {
                    for (int x = 0; x < bitmap.PixelWidth; ++x)
                    {
                        int pixel = bitmap.Pixels[bitmap.PixelWidth * y + x];
                        imageData.SetPixel(x, y,

                        (byte)((pixel >> 16) & 0xFF),
                        (byte)((pixel >> 8) & 0xFF),

                        (byte)(pixel & 0xFF), (byte)((pixel >> 24) & 0xFF)
                        );
                    }
                }
            }
            catch (System.Security.SecurityException)
            {
                //Todo decent message
            }

            //Encode imageData to PNG-format in a memorystream 
            ImageTools.IO.Png.PngEncoder enc = new ImageTools.IO.Png.PngEncoder();
            MemoryStream pngStream = new MemoryStream();
            enc.Encode(imageData, pngStream);

            //rewind memorystream
            pngStream.Position = 0;

            //read memorystream which contains png'd image and write to file
            StreamReader sr = new StreamReader(pngStream);
            byte[] binaryData = new byte[pngStream.Length];
            long bytesRead = pngStream.Read(binaryData, 0, (int)pngStream.Length); 
            using (Stream stream = sfd.OpenFile())
            {
                stream.Write(binaryData, 0, binaryData.Length);
                stream.Close();
            }
Coordinator
Jul 18, 2009 at 12:58 PM

Thanks for this example, avbers, but I dont understand why you need a seperate memory stream. You can write directly to the file stream.

I have written some extension methods and a short howto:

http://imagetools.codeplex.com/Wiki/View.aspx?title=Write%20the%20content%20of%20a%20canvas%20to%20a%20file

 

Just a short preview. This is all you need:

ImageTools myImage = MyCanvas.ToImage();

SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Image Files (*.png)|*.png";

if (sfd.ShowDialog() == true)
{
   using (Stream stream = sfd.OpenFile())
   {
      myImage.WriteToStream(stream);
   }
}

 

Jul 18, 2009 at 2:26 PM

Of course it can.. I had some in-between steps to fiddle with the stream, but removed it..

Great work on those extension-methods, which simplify work for most people..

 

Jul 19, 2009 at 7:53 PM

Excellent, thanks both for the brilliant responses.

Sorry about my ignorance on imaging, image file formats :-).

Thanks

  Braulio

Sep 11, 2009 at 7:01 AM

using (Stream stream = sfd.OpenFile())
            {
                stream.Write(binaryData, 0, binaryData.Length);
                stream.Close();
            }

Instead of asking user to save the file to local system.. how can use the stream to save the file on the server?

Sample code would be appreciated.

Pooran

Sep 22, 2009 at 11:13 AM

I found an alternative.. I am generating a base64 string using code from http://stackoverflow.com/questions/1139200/using-fjcore-to-encode-silverlight-writeablebitmap and saving it as an image in ASP.Net code.. hope that helps somebody