如何使用Xamarin-Forms下载图像并将其保存在本地存储中?

时间:2018-06-26 08:25:26

标签: c# xamarin.forms

我想下载图像并将其存储在本地存储中的特定文件夹中。

我正在使用它下载图像:

var imageData = await AzureStorage.GetFileAsync(ContainerType.Image, uploadedFilename);
var img = ImageSource.FromStream(() => new MemoryStream(imageData));

3 个答案:

答案 0 :(得分:7)

创建FileService接口

在共享代码中,创建一个新接口,例如,名为IFileService.cs

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

实施Android

在您的android项目中,创建一个名为“ Fileservice.cs”的新类。

确保它源自之前创建的接口,并使用依赖项信息对其进行修饰:

[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);
            }
        }
    }
}

实施iOS iOS的实现基本相同:

[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);
            }
        }
    }
}

为了保存文件,请在共享代码中调用

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

应该很好。

答案 1 :(得分:0)

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);
}

在这里您必须使用来自xamarin形式PCL的依赖项服务才能从android项目中调用此方法。这会将您的图像存储到公用文件夹中。如果我还有时间使用iOS进行演示,将对其进行编辑。

答案 2 :(得分:0)

我真的很喜欢Karan的方法。

我将两者结合在一起,我想在这里分享。实际上效果很好。

$ cmake -DCMAKE_C_COMPILER:STRING="/usr/bin/clang-7" -DCMAKE_CXX_COMPILER:STRING="/usr/bin/clang++-7" -DCMAKE_C_FLAGS="-fPIC" -C../test-suite/cmake/caches/O3.cmake -DTEST_SUITE_SPEC2017_ROOT:STRING="../speccpu2017" ../test-suite
...
$ make
...
In file included from /home/speccpu2017/benchspec/CPU/526.blender_r/src/blender/source/blender/render/intern/raytrace/rayobject_qbvh.cpp:37:
In file included from /home/speccpu2017/benchspec/CPU/526.blender_r/src/blender/source/blender/render/intern/raytrace/vbvh.h:34:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/algorithm:61:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:63:

/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/numeric_traits.h:63:25: error: expected member name or ';' after
      declaration specifiers
      static const bool __is_signed = __glibcxx_signed(_Value);
      ~~~~~~~~~~~~~~~~~ ^

/usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/ext/numeric_traits.h:74:50: error: expected unqualified-id
    const bool __numeric_traits_integer<_Value>::__is_signed;
                                                 ^    
[Long error. Truncated for clarity]