locked
Saving a WriteableBitmap to PNG or JPEG in a Metro app RRS feed

  • Question

  • Hi,

    Is there a builtin way to save the contents of a WriteableBitmap to a StorageFile as a .png or .jpg image in Metro?

    So far, I've found the http://writeablebitmapex.codeplex.com/ project to get the bitmap's bytes but that's pretty much it.

    Thanks,
    Gionata Mettifog

    Tuesday, June 26, 2012 9:28 AM

Answers

  • You can get the pixels from the WriteableBitmap with its PixelBuffer property. You can then encode that to a file with a BitmapEncoder object.

    Something like the following:

                FileSavePicker picker = new FileSavePicker();
                picker.FileTypeChoices.Add("JPG File", new List<string>() { ".jpg" });
                StorageFile file = await picker.PickSaveFileAsync();
    
                IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite);
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
                Stream pixelStream = bmp.PixelBuffer.AsStream();
                byte[] pixels = new byte[pixelStream.Length];
                await pixelStream.ReadAsync(pixels, 0, pixels.Length);
    
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) bmp.PixelWidth, (uint) bmp.PixelHeight,96.0,96.0, pixels);
                await encoder.FlushAsync();
      

    • Proposed as answer by Can Bilgin Wednesday, June 27, 2012 8:50 AM
    • Marked as answer by Min ZhuMember Monday, July 9, 2012 8:33 AM
    Tuesday, June 26, 2012 7:32 PM
    Moderator

All replies

  • You can get the pixels from the WriteableBitmap with its PixelBuffer property. You can then encode that to a file with a BitmapEncoder object.

    Something like the following:

                FileSavePicker picker = new FileSavePicker();
                picker.FileTypeChoices.Add("JPG File", new List<string>() { ".jpg" });
                StorageFile file = await picker.PickSaveFileAsync();
    
                IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite);
                BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
                Stream pixelStream = bmp.PixelBuffer.AsStream();
                byte[] pixels = new byte[pixelStream.Length];
                await pixelStream.ReadAsync(pixels, 0, pixels.Length);
    
                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) bmp.PixelWidth, (uint) bmp.PixelHeight,96.0,96.0, pixels);
                await encoder.FlushAsync();
      

    • Proposed as answer by Can Bilgin Wednesday, June 27, 2012 8:50 AM
    • Marked as answer by Min ZhuMember Monday, July 9, 2012 8:33 AM
    Tuesday, June 26, 2012 7:32 PM
    Moderator
  • Hi:

       Your  sample  saved  ink to a png file.  But I want to define ink as png and Convert.ToBase64String() . then upload to My Server. I don't know how to do it.

     My code on WP7 :

    WriteableBitmap wbBitmap = new WriteableBitmap(inkSignature, new TranslateTransform());
    Image image = new Image();
    image.Width = 164;
    image.Height = 120;
    image.Source = wbBitmap;
    PngEncoder enc = new PngEncoder();
    using (MemoryStream pngBytes = new MemoryStream())
    {
        enc.Encode(image.ToImage(), pngBytes);
       App.DealData.Add("signature",Convert.ToBase64String(pngBytes.ToArray()));
    }
    

    According to you sample. I have tried 

    InMemoryRandomAccessStream imas = new InMemoryRandomAccessStream();
    await _inkManager.SaveAsync(imas);
    WriteableBitmap wb = new WriteableBitmap(164, 120);
    WriteableBitmap wb = await wp.FromStream(imas);

    I don't know how to do  next. How to define weiteableBitmap to png and convertobase64String.

    Saturday, June 30, 2012 8:27 AM