locked
How to save a Bitmap Image from a Share target.. RRS feed

  • Question

  • Hi everyone,

    I've been researching a lot about this and i only have found threads such as how to crop a bitmap image etc, but what i'm trying to achieve is that , i have a photo browser app and this app is a Share source and a Share target, so when i open the facebook app for example and then from there i use the Share Charm to share its contents to my PhotoBrowser app, the Facebook screenshot successfully shows on my App share target page, so my question is , how can i grab that image that shows on my ShareCharm and save it to disk in order to allow me to add to my photoBrowser pics?
    here is the code for retrieving the bitmap image :

     if (this.sharedBitmapStreamRef != null)
                        {
                            IRandomAccessStreamWithContentType bitmapStream = await this.sharedBitmapStreamRef.OpenReadAsync();
                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.SetSource(bitmapStream);
                            ImageHolder.Source = bitmapImage;
                    
                            ImageArea.Visibility = Visibility.Visible;
                            
                        }
    

    so everything is working as expected and i can see the image on the right side of my Share Charm however i cant figure out a way to save that image to disk!!
    Any help is greatly appreciated..

    Kind regards,

    C# user

    Thursday, February 6, 2014 1:03 AM

Answers

  • Hi MrDebugging,

    May I understand your question as: You need a way to save a BitmapImage to a local storage.

    You can't save or modify a BitmapImage. You need to use a WriteableBitmap class instead, you could find a sample code for reading the WriteableBitmap in the page, I believe that writing is not a difficult thing.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Hi again,
    i finally found the solution, so this is the code:

     if (this.sharedBitmapStreamRef != null)
                        {
                            IRandomAccessStreamWithContentType bitmapStream = await this.sharedBitmapStreamRef.OpenReadAsync();
                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.SetSource(bitmapStream);
                            ImageHolder.Source = bitmapImage;
                          
                            StorageFile imageFile =  (StorageFile) sharedStorageItems[0];
    
                            WriteableBitmap writeableBitmap = null;
                            using (bitmapStream = await imageFile.OpenReadAsync())
                            {
                               BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(
                                  bitmapStream);
    
                               BitmapTransform dummyTransform = new BitmapTransform();
                               PixelDataProvider pixelDataProvider =
                                  await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, 
                                  BitmapAlphaMode.Premultiplied, dummyTransform, 
                                  ExifOrientationMode.RespectExifOrientation,
                                  ColorManagementMode.ColorManageToSRgb);
                               byte[] pixelData = pixelDataProvider.DetachPixelData();
    
                               writeableBitmap = new WriteableBitmap(
                                  (int)bitmapDecoder.OrientedPixelWidth,
                                  (int)bitmapDecoder.OrientedPixelHeight);
                               using (Stream pixelStream = writeableBitmap.PixelBuffer.AsStream())
                               {
                                  await pixelStream.WriteAsync(pixelData, 0, pixelData.Length);
                               }
                            }
                           await  WriteableBitmapToStorageFile(writeableBitmap, FileFormat.Png);
    

    the sharedStorageItems is declared and implemented here:

    //declared here at the top of the page class
     private IReadOnlyList<IStorageItem> sharedStorageItems;
    
     if (this.shareOperation.Data.Contains(StandardDataFormats.StorageItems))
                    {
                        try
                        {
                            this.sharedStorageItems = await this.shareOperation.Data.GetStorageItemsAsync();
                        }
                        catch (Exception ex)
                        {
                            NotifyUserBackgroundThread("Failed GetStorageItemsAsync - " + ex.Message, NotifyType.ErrorMessage);
                        }
                    }

    and the method used to create the file:

     private async Task<StorageFile> WriteableBitmapToStorageFile(WriteableBitmap WB, FileFormat fileFormat)
            {
                string FileName = "MyFile.";
                Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
                switch (fileFormat)
                {
                    case FileFormat.Jpeg:
                        FileName += "jpeg";
                        BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
                        break;
    
                    case FileFormat.Png:
                        FileName += "png";
                        BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
                        break;
    
                    case FileFormat.Bmp:
                        FileName += "bmp";
                        BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
                        break;
    
                    case FileFormat.Tiff:
                        FileName += "tiff";
                        BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
                        break;
    
                    case FileFormat.Gif:
                        FileName += "gif";
                        BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
                        break;
                }
    
                var file = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(FileName, CreationCollisionOption.GenerateUniqueName);
                using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
                    Stream pixelStream = WB.PixelBuffer.AsStream();
                    byte[] pixels = new byte[pixelStream.Length];
                    await pixelStream.ReadAsync(pixels, 0, pixels.Length);
    
                    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
                                        (uint)WB.PixelWidth,
                                        (uint)WB.PixelHeight,
                                        96.0,
                                        96.0,
                                        pixels);
                    await encoder.FlushAsync();
                }
                return file;
            }
    
            private enum FileFormat
            {
                Jpeg,
                Png,
                Bmp,
                Tiff,
                Gif
            }

    i hope this helps someone who comes across this problem..
    kind regards,

    C# user


    Thursday, February 6, 2014 7:30 PM
  • Hi dear Moderator,

    thanks for replying and yeah you got that right, i need to write a bitmap image to a local storage, more specifically the bitmap shared through an app ...
    i've read some threads about the writableBitmap class but havent found the right topic yet, so i will keep reseaching on this topic but i really appreciate if someone can drop a code sample here or even point me to a direction by posting any link here..
    Thanks again,
    C# user

    • Marked as answer by MrDebugging Thursday, February 6, 2014 7:41 PM
    Thursday, February 6, 2014 4:18 PM

All replies

  • Hi MrDebugging,

    May I understand your question as: You need a way to save a BitmapImage to a local storage.

    You can't save or modify a BitmapImage. You need to use a WriteableBitmap class instead, you could find a sample code for reading the WriteableBitmap in the page, I believe that writing is not a difficult thing.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Thursday, February 6, 2014 8:45 AM
    Moderator
  • Hi dear Moderator,

    thanks for replying and yeah you got that right, i need to write a bitmap image to a local storage, more specifically the bitmap shared through an app ...
    i've read some threads about the writableBitmap class but havent found the right topic yet, so i will keep reseaching on this topic but i really appreciate if someone can drop a code sample here or even point me to a direction by posting any link here..
    Thanks again,
    C# user

    • Marked as answer by MrDebugging Thursday, February 6, 2014 7:41 PM
    Thursday, February 6, 2014 4:18 PM
  • Hi MrDebugging,

    May I understand your question as: You need a way to save a BitmapImage to a local storage.

    You can't save or modify a BitmapImage. You need to use a WriteableBitmap class instead, you could find a sample code for reading the WriteableBitmap in the page, I believe that writing is not a difficult thing.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Hi again,
    i finally found the solution, so this is the code:

     if (this.sharedBitmapStreamRef != null)
                        {
                            IRandomAccessStreamWithContentType bitmapStream = await this.sharedBitmapStreamRef.OpenReadAsync();
                            BitmapImage bitmapImage = new BitmapImage();
                            bitmapImage.SetSource(bitmapStream);
                            ImageHolder.Source = bitmapImage;
                          
                            StorageFile imageFile =  (StorageFile) sharedStorageItems[0];
    
                            WriteableBitmap writeableBitmap = null;
                            using (bitmapStream = await imageFile.OpenReadAsync())
                            {
                               BitmapDecoder bitmapDecoder = await BitmapDecoder.CreateAsync(
                                  bitmapStream);
    
                               BitmapTransform dummyTransform = new BitmapTransform();
                               PixelDataProvider pixelDataProvider =
                                  await bitmapDecoder.GetPixelDataAsync(BitmapPixelFormat.Bgra8, 
                                  BitmapAlphaMode.Premultiplied, dummyTransform, 
                                  ExifOrientationMode.RespectExifOrientation,
                                  ColorManagementMode.ColorManageToSRgb);
                               byte[] pixelData = pixelDataProvider.DetachPixelData();
    
                               writeableBitmap = new WriteableBitmap(
                                  (int)bitmapDecoder.OrientedPixelWidth,
                                  (int)bitmapDecoder.OrientedPixelHeight);
                               using (Stream pixelStream = writeableBitmap.PixelBuffer.AsStream())
                               {
                                  await pixelStream.WriteAsync(pixelData, 0, pixelData.Length);
                               }
                            }
                           await  WriteableBitmapToStorageFile(writeableBitmap, FileFormat.Png);
    

    the sharedStorageItems is declared and implemented here:

    //declared here at the top of the page class
     private IReadOnlyList<IStorageItem> sharedStorageItems;
    
     if (this.shareOperation.Data.Contains(StandardDataFormats.StorageItems))
                    {
                        try
                        {
                            this.sharedStorageItems = await this.shareOperation.Data.GetStorageItemsAsync();
                        }
                        catch (Exception ex)
                        {
                            NotifyUserBackgroundThread("Failed GetStorageItemsAsync - " + ex.Message, NotifyType.ErrorMessage);
                        }
                    }

    and the method used to create the file:

     private async Task<StorageFile> WriteableBitmapToStorageFile(WriteableBitmap WB, FileFormat fileFormat)
            {
                string FileName = "MyFile.";
                Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
                switch (fileFormat)
                {
                    case FileFormat.Jpeg:
                        FileName += "jpeg";
                        BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
                        break;
    
                    case FileFormat.Png:
                        FileName += "png";
                        BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
                        break;
    
                    case FileFormat.Bmp:
                        FileName += "bmp";
                        BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
                        break;
    
                    case FileFormat.Tiff:
                        FileName += "tiff";
                        BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
                        break;
    
                    case FileFormat.Gif:
                        FileName += "gif";
                        BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
                        break;
                }
    
                var file = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(FileName, CreationCollisionOption.GenerateUniqueName);
                using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
                {
                    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
                    Stream pixelStream = WB.PixelBuffer.AsStream();
                    byte[] pixels = new byte[pixelStream.Length];
                    await pixelStream.ReadAsync(pixels, 0, pixels.Length);
    
                    encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
                                        (uint)WB.PixelWidth,
                                        (uint)WB.PixelHeight,
                                        96.0,
                                        96.0,
                                        pixels);
                    await encoder.FlushAsync();
                }
                return file;
            }
    
            private enum FileFormat
            {
                Jpeg,
                Png,
                Bmp,
                Tiff,
                Gif
            }

    i hope this helps someone who comes across this problem..
    kind regards,

    C# user


    Thursday, February 6, 2014 7:30 PM