13

I want to download an image and store it in specific folder in local storage.

I am using this to download image:

var imageData = await AzureStorage.GetFileAsync(ContainerType.Image, uploadedFilename);
var img = ImageSource.FromStream(() => new MemoryStream(imageData));
Senthamizh
  • 281
  • 1
  • 4
  • 12
Parmendra
  • 227
  • 1
  • 4
  • 12
  • What have you tried and how, exactly, is that not working? Please provide a [**Minimal, Complete, and Verifiable example**](//stackoverflow.com/help/mcve) - without that we probably won't be able to help you. – Frauke Jun 26 '18 at 08:39
  • I dont know the way. What should I do for that.... Can you please give me any idea or any link – Parmendra Jun 26 '18 at 08:47
  • I have a Android link, But how i can achieve in xamarin.forms https://stackoverflow.com/questions/8560501/android-save-image-into-gallery – Parmendra Jun 26 '18 at 09:00
  • Start by reading up on file handling in Xamarin.Forms. That should give you a good starting point. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/files?tabs=vswin – Frauke Jun 26 '18 at 09:29

3 Answers3

25

Create a FileService interface

in your Shared Code, create a new Interface, for instance, called IFileService.cs

 public interface IFileService
 {
      void SavePicture(string name, Stream data, string location="temp");
 }

Implementation Android

In your android project, create a new class called "Fileservice.cs".

Make sure it derives from your interface created before and decorate it with the dependency information:

[assembly: Dependency(typeof(FileService))]
namespace MyApp.Droid
{
    public class FileService : IFileService
    {
        public void SavePicture(string name, Stream data, string location = "temp")
        {
            var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            documentsPath = Path.Combine(documentsPath, "Orders", location);
            Directory.CreateDirectory(documentsPath);

            string filePath = Path.Combine(documentsPath, name);

            byte[] bArray = new byte[data.Length];
            using (FileStream fs = new FileStream(filePath , FileMode.OpenOrCreate))
            {
                using (data)
                {
                    data.Read(bArray, 0, (int)data.Length);
                }
                int length = bArray.Length;
                fs.Write(bArray, 0, length);
            }
        }
    }
}

Implementation iOS The implementation for iOS is basically the same:

[assembly: Dependency(typeof(FileService))]
namespace MyApp.iOS
{
    public class FileService: IFileService
    {
        public void SavePicture(string name, Stream data, string location = "temp")
        {
            var documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            documentsPath = Path.Combine(documentsPath, "Orders", location);
            Directory.CreateDirectory(documentsPath);

            string filePath = Path.Combine(documentsPath, name);

            byte[] bArray = new byte[data.Length];
            using (FileStream fs = new FileStream(filePath , FileMode.OpenOrCreate))
            {
                using (data)
                {
                    data.Read(bArray, 0, (int)data.Length);
                }
                int length = bArray.Length;
                fs.Write(bArray, 0, length);
            }
        }
    }
}

In order to save your file, in your shared code, you call

DependencyService.Get<IFileService>().SavePicture("ImageName.jpg", imageData, "imagesFolder");

and should be good to go.

Markus Michel
  • 2,289
  • 10
  • 18
  • 2
    i was trying to edit the awnser, but can't edit only 1 char, in the shared code, you get the Interface on the DependencyService, not the project implementation class DependencyService.Get().SavePicture("ImageName.jpg", imageData, "imagesFolder"); – Ricardo Dias Morais Sep 03 '19 at 10:44
  • 2
    Should it automatically create a folder named "temp" or where does it save the image? I ran the code, and it compiled, but I can't find the image that I saved – Lukas Méndez Duus Feb 14 '20 at 22:19
  • 1
    Looks like this could all be done from the shared project, couldn't it? – Michal Diviš Feb 15 '21 at 09:40
4
public void DownloadImage(string URL)
{
    var webClient = new WebClient();
    webClient.DownloadDataCompleted += (s, e) =>
    {
        byte[] bytes = new byte[e.Result.Length];
        bytes=e.Result; // get the downloaded data
        string documentsPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).AbsolutePath;

        var partedURL = URL.Split('/');
        string localFilename = partedURL[partedURL.Length-1];
        string localPath = System.IO.Path.Combine(documentsPath, localFilename);
        File.WriteAllBytes(localPath, bytes); // writes to local storage
        Application.Current.MainPage.IsBusy = false;
        Application.Current.MainPage.DisplayAlert("Download", "Download Finished", "OK");
        MediaScannerConnection.ScanFile(Forms.Context,new string[] { localPath }, null, null);
    };
    var url = new Uri(URL);
    webClient.DownloadDataAsync(url);
}

Here you have to use dependency service from xamarin forms PCL to call this method from android project.This will store your image to public folder. Will edit this if i get time to make a demo with iOS also.

Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
Karan Rami
  • 321
  • 2
  • 11
2

I really liked Karan's approach.

I've made a sort of combination of them both and I wanted to share them here. Worked pretty well actually.

public String DownloadImage(Uri URL)
{
    WebClient webClient = new WebClient();

    string folderPath   = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Images", "temp");
    string fileName     = URL.ToString().Split('/').Last();
    string filePath     = System.IO.Path.Combine(folderPath, fileName);

    webClient.DownloadDataCompleted += (s, e) =>
    {
        Directory.CreateDirectory(folderPath);

        File.WriteAllBytes(filePath, e.Result);
    };

    webClient.DownloadDataAsync(URL);

    return filePath;
}
osoclever
  • 373
  • 7
  • 16