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

5

我有一张保存在我的应用程序中外部存储器上的物品图片。我想在我的共享项目中使用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);

你的应用只适用于安卓系统吗? - jzeferino
@jzeferino 首先是的。但我相信,即使对于iOS版本,如果我从自己的应用程序中获取此路径,则它也将是正确的并可供阅读的。 - Episodex
在最终版本中,我想将图像存储在应用程序的私有文件夹中,而不是外部存储。因此,解决方案也可以从例如 Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) 读取。 - Episodex
1个回答

5

你的Xamarin Forms PCL不知道Android中的URI是什么,因为它是平台特定的,所以:

ImageSource.FromFile(path);

无法工作。

如果您正在处理特定于平台的功能,即从Android加载图像。我建议采用以下方法:

在Xamarin Forms PCL上创建一个接口,如:

public interface IPhoto
{
    Task<Stream> GetPhoto ();
}

然后在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;
            }
        }
    }

在Xamarin Forms PCL代码中获取图像:
var image = ImageSource.FromStream ( () => await DependencyService.Get<IPhoto>().GetPhoto());

欲了解更多详细信息,请咨询此链接

注意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. 
    }
}

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

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


为什么你要使用共享项目?如果遇到任何问题,请让我知道。因为你在使用共享项目,所以你可以用#ifdef来处理。在我看来,你应该使用PCL。 - jzeferino
我在答案中添加了一个共享项目解决方案。 - jzeferino
使用ImageSource.FromUri和互联网上的图像URL一起工作并显示图像。我将图片路径作为参数发送,因为每个项目都有自己分配的图片。它保存在数据库中。 - Episodex
让我们在聊天中继续这个讨论。点击此处进入聊天室 - jzeferino
2
对我来说,ImageSource.FromFile(path); 在使用 Android 特定的文件路径时完美地工作。不需要依赖服务。 - testing
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接