将 Image.Source 设置为 Xamarin.Forms 中外部存储中的文件

Epi*_*dex 5 xamarin xamarin.forms

我在外部存储中有一张项目的图片(在我的应用程序中有意保存)。我想Image在我的共享项目中显示这张图片。

Image.Source接受ImageSource类型的对象。我试过了ImageSource.FromFileImageSource.FromStream甚至ImageSource.FromUri。结果始终是图像不显示(没有错误或异常)。File.Open我通过首先用上面一行打开文件来验证文件路径是否正确。

显示正常存储中的图片而不是资产/资源等的正确方法是什么?

此代码不起作用

var path = "/storage/emulated/0/Pictures/6afbd8c6-bb1e-49d3-838c-0fa809e97cf1.jpg" //in real app the path is taken from DB
var image = new Image() {Aspect = Aspect.AspectFit, WidthRequest = 200, HeightRequest = 200};
image.Source = ImageSource.FromFile(path);
Run Code Online (Sandbox Code Playgroud)

jze*_*ino 5

您的 Xamarin Forms PCL 不知道它来自 Android 的 URI,因为它是特定于平台的,因此:

ImageSource.FromFile(path);
Run Code Online (Sandbox Code Playgroud)

行不通的。

在这种情况下,您正在处理特定于平台的功能,即从 Android 加载图像。我建议这种方法:

在 Xamarin Forms PCL 上创建一个界面,例如:

public interface IPhoto
{
    Task<Stream> GetPhoto ();
}
Run Code Online (Sandbox Code Playgroud)

然后在 Android 中实现该接口并在以下位置注册实现DependencyService

[assembly: Xamarin.Forms.Dependency(typeof(PhotoImplementation))]
    namespace xpto
    {
        public class PhotoImplementation : Java.Lang.Object, IPhoto
        {
            public async Task<Stream> GetPhoto()
            {
                // Open the photo and put it in a Stream to return       
                var memoryStream = new MemoryStream();

                using (var source = System.IO.File.OpenRead(path))
                {
                    await source.CopyToAsync(memoryStream);
                }

                return memoryStream;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

在 Xamarin Forms PCL 代码中获取图像:

var image = ImageSource.FromStream ( () => await DependencyService.Get<IPhoto>().GetPhoto());
Run Code Online (Sandbox Code Playgroud)

更详细的可以参考这个

注意1:如果您也实现了 IPhoto 接口,这将在 iOS 上工作。

注意2:Xamarin-Forms-Labs 中有一个针对此类功能的有用库,名为Camera


更新(共享项目解决方案)

根据评论中的要求,要在共享项目中使用它而不是 PCL,我们可以这样做。

1 - 将其放入IPhotoInterface共享项目中。

2 - 在Android/iOS项目中实现接口:

public class PhotoImplementation : IPhoto
{
    public async Task<Stream> GetPhoto()
    {
        // Open the photo and put it in a Stream to return. 
    }
}
Run Code Online (Sandbox Code Playgroud)

3 - 在共享项目中使用它:

IPhoto iPhotoImplementation;

#if __ANDROID__
iPhotoImplementation = new shared_native.Droid.GetPicture();

#elif __IOS__
iPhotoImplementation = new shared_native.iOS.GetPicture();

#endif

var image = ImageSource.FromStream ( () => await iPhotoImplementation.GetPhoto());
Run Code Online (Sandbox Code Playgroud)

注意:shared_native是我的解决方案的命名空间,Droid/iOS是 Android 和 iOS 的项目。

  • 对我来说,`ImageSource.FromFile(path);` 与 Android 特定文件路径完美配合。无需依赖服务。 (2认同)