locked
How to save BitmapImage after converted from Base64 into a Folder

    Question

  • I used below code to convert Base64 string into BitmapImage.After this, I need to save this image file in a folder Which i added to the project.

    The problem:

     error encountered here !!!
    await FileIO.WriteBufferAsync(sampleFile, buffer);

    How can i solve this? Thanks your help is greatly appreciated.


    public async Task Base64StringToBitmapTask(string Base64source,string Filenm)
     {

      var ims = new InMemoryRandomAccessStream();   

      var bytes = Convert.FromBase64String(Base64source);
      var dataWriter = new DataWriter(ims);       
      dataWriter.WriteBytes(bytes);        
      await dataWriter.StoreAsync();       
      ims.Seek(0);

      var bm = new BitmapImage();
      bm.SetSource(ims);        

      byte[] pixeBuffer = null;

      using (MemoryStream ms = new MemoryStream())
       {
          WriteableBitmap wb = new WriteableBitmap(bm.PixelWidth,bm.PixelHeight);
           await wb.SetSourceAsync(ims);

          Stream s1 = wb.PixelBuffer.AsStream();
           s1.CopyTo(ms);

           pixeBuffer = ms.ToArray();

         }
      await InsertImageInFolder(pixeBuffer, Filenm);

     }


     private async Task InsertImageInFolder(byte[] buffer, string filename)
      {


       StorageFolder folder = ApplicationData.Current.LocalFolder;

        //---Can the folder which I added to the prject :

        StorageFolder subfolder = await StorageFolder.GetFolderFromPathAsync("ms-appx:///ProductImages");

        StorageFile  sampleFile = await subfolder.GetFileAsync(filename);     


       error encountered here !!!

            await FileIO.WriteBufferAsync(sampleFile, buffer);

     

      }

    Monday, February 24, 2014 1:42 PM

Answers

  • WriteBufferAsync's buffer needs to be an IBuffer not a byte[]. You can convert with the AsBuffer extension method.
    Monday, February 24, 2014 3:50 PM
    Owner
  • You need to add AddBuffer's namespace to your using.

    Its not clear what your code is trying to do with the InMemoryRandomAccessStream. It looks like you're trying to initialize from it without ever adding data to it. Why?

    What format is the data is in base64 string? You can convert it to a buffer then either save it out directly (if its a file format) or pass it to a BitmapEncoder (if its raw bytes) and then save that.

    Simplify your problem to do one thing at a time and get that to work first before complicating things.

    --Rob

    Wednesday, February 26, 2014 4:24 PM
    Owner
  • Step one: simplify the problem.

    Make sure you can download the base64 string successfully and save it out.

    Then add decoding and save it to disk: make sure you can decode it to a binary and save it out. If the original was a jpg file then it doesn't need further encoding.

    Make sure you can open and read that file. If not, then you need to fix the base64 encoding. If so, then you know you're good up to this point.

    Only after you know you have the download and decode working correctly should you move on to reading it into your BitmapImage.

    Tuesday, March 04, 2014 12:16 AM
    Owner

All replies

  • WriteBufferAsync's buffer needs to be an IBuffer not a byte[]. You can convert with the AsBuffer extension method.
    Monday, February 24, 2014 3:50 PM
    Owner
  • I am not entirely familiar with Base64, image , conversion and saving file in StorageFolder

    I encountered the errors and I had used AsBuffer for byte[]

    1) The component cannot be found. (Exception from HRESULT: 0x88982F50)

    2) incorrect paramter
       WriteableBitmap wb = new WriteableBitmap(bm.PixelWidth,bm.PixelHeight);

    So, I think, it has to do with

    a) Conversion from Base64 to bitmapimage
    b) Saving Bitmapimage to Buffer and save it as file in Folder


    Your help is greatly appreciated.

    --- Convert Base64 image string, the filename format is  namexxxxx.jpg

     public async Task Base64StringToBitmapTask(string Base64source,string Filenm)
            {

                var ims = new InMemoryRandomAccessStream();
                var bytes = Convert.FromBase64String(Base64source);

                var dataWriter = new DataWriter(ims);

             
                dataWriter.WriteBytes(bytes);
        
                await dataWriter.StoreAsync();
            
                ims.Seek(0);
                var bm = new BitmapImage();
                bm.SetSource(ims);     
               
                byte[] pixeBuffer = null;
                      
                using (MemoryStream ms = new MemoryStream())
                {

    Error for (2) Here:
                   //-- incorrect paramter
                    //WriteableBitmap wb = new WriteableBitmap(bm.PixelWidth,bm.PixelHeight);

                   //-- this Ok
                    WriteableBitmap wb = new WriteableBitmap(200, 200);

    Error for (1) here:
                         await wb.SetSourceAsync(ims);
     
                        Stream s1 = wb.PixelBuffer.AsStream();
                        s1.CopyTo(ms);

                        pixeBuffer = ms.ToArray();

                }

                await InsertImageInFolder(pixeBuffer, Filenm);
               
            }

     

     private async Task InsertImageInFolder(byte[] buffer, string filename)
            {


                IBuffer Ibr = buffer.AsBuffer();

                StorageFolder folder = ApplicationData.Current.LocalFolder;     

                StorageFolder subfolder = await folder.GetFolderAsync("ProductImages");

                //???
                //StorageFolder subfolder = await StorageFolder.GetFolderFromPathAsync("ms-appx:///ProductImages");
             
               
                await subfolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);

                 StorageFile  sampleFile = await subfolder.GetFileAsync(filename);

                 await FileIO.WriteBufferAsync(sampleFile, Ibr);

                 MessageDialog msg = new MessageDialog("Ok", "Insert Image");
                 await msg.ShowAsync();
           
            }

     

     

     

     

    Tuesday, February 25, 2014 2:45 PM
  • Any1 can help me on this?
    Wednesday, February 26, 2014 8:14 AM
  • You need to add AddBuffer's namespace to your using.

    Its not clear what your code is trying to do with the InMemoryRandomAccessStream. It looks like you're trying to initialize from it without ever adding data to it. Why?

    What format is the data is in base64 string? You can convert it to a buffer then either save it out directly (if its a file format) or pass it to a BitmapEncoder (if its raw bytes) and then save that.

    Simplify your problem to do one thing at a time and get that to work first before complicating things.

    --Rob

    Wednesday, February 26, 2014 4:24 PM
    Owner
  • I could not find any similiar sample code in the internet. I spent hours and still got not solve it and I am not sure the entire process is correct.

    This is what I wanted to achieve.
    a) receive from Webservice and Convert the base64 image string into bitmapimage
    b) Save it in the folder call ProductImages which I added into the project.

    here my new processes:

    a) Convert the base64 image string

    - This base64 image string can be Jpg, png format received from webservice.
    - Assume for now, it is Jpg.

    1) If I convert it to stream, if this is a proper image byte which can be used to create bitmapImage as below?

    I use InMemoryRandomAccessStream.

    public async Task Base64StringToBitmapTask(string Base64source,string Filenm)
    {

        var ims = new InMemoryRandomAccessStream();       

        var bytes = Convert.FromBase64String(Base64source);
        var dataWriter = new DataWriter(ims);       
        dataWriter.WriteBytes(bytes);         
        await dataWriter.StoreAsync();
      
       - is below the proper image stream?
     
        ims.Seek(0);  

    2.0) assume ims is the proper image stream. Convert it to byte[]

      var byt = new byte[ims.Size];

      var reader = new DataReader(ims.GetInputStreamAt(0));
      await reader.LoadAsync((uint)ims.Size);
      reader.ReadBytes(byt);

      byte[] pixeBuffer = byt.ToArray();

    2.1) Save it as bitmapImage in the folder call ProductImage inside project

          await InsertImageInFolder(pixeBuffer, Filenm);

    }


    3.0) add these :

    3.1) using System.Runtime.InteropServices.WindowsRuntime;

    3.2) Pass in the buffer and filename like beer.jpg


    private async Task InsertImageInFolder(byte[] buffer, string filename)
     {

      IBuffer Ibr = buffer.AsBuffer();

      StorageFolder folder = ApplicationData.Current.LocalFolder;

      
       //??? use to use ?
       //StorageFolder subfolder = await folder.GetFolderAsync("ProductImages");
       //StorageFolder subfolder = await StorageFolder.GetFolderFromPathAsync("ms-appx:///ProductImages");
     
    StorageFolder subfolder = await StorageFolder.GetFolderFromPathAsync("ProductImages");

       //-- create a file
     
      var myImageFilename = await subfolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
     
      //-- get the file
      StorageFile  sampleFile = await subfolder.GetFileAsync(filename);

        await FileIO.WriteBufferAsync(sampleFile, Ibr);

        MessageDialog msg = new MessageDialog("Ok", "Insert Image");
        await msg.ShowAsync();
           
       }


    -- The problem :

    There is no error message and the process InsertImageInFolder() never stop like going into infinity. After a few minutes later, I stop it and there was no Bitmapimage file is saved.


    Can you point out what I need to do if above method not correct.

     

     

     

    Sunday, March 02, 2014 2:18 PM
  • Step one: simplify the problem.

    Make sure you can download the base64 string successfully and save it out.

    Then add decoding and save it to disk: make sure you can decode it to a binary and save it out. If the original was a jpg file then it doesn't need further encoding.

    Make sure you can open and read that file. If not, then you need to fix the base64 encoding. If so, then you know you're good up to this point.

    Only after you know you have the download and decode working correctly should you move on to reading it into your BitmapImage.

    Tuesday, March 04, 2014 12:16 AM
    Owner