Set Image.Source to file in external storage in Xamarin.Forms

前端 未结 1 1401
星月不相逢
星月不相逢 2020-12-11 20:34

I have a picture of item in external storage (that was saved by intent in my app). I want to display this picture in Image view in my shared project.

相关标签:
1条回答
  • 2020-12-11 21:03

    Your Xamarin Forms PCL don't know what its a URI from Android beacuse its platform specific, so:

    ImageSource.FromFile(path);
    

    won't work.

    In that case you are handling platform specific features, that is loading an image from Android. I suggest this approach:

    Create an interface on Xamarin Forms PCL like:

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

    Then in Android you implement that interface and register the implementation in 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;
                }
            }
        }
    

    In the Xamarin Forms PCL code get the image:

    var image = ImageSource.FromStream ( () => await DependencyService.Get<IPhoto>().GetPhoto());
    

    For more detail you can consult this.

    NOTE1: This will work on iOS if you implement the interface IPhoto too.

    NOTE2: There exist a helpful library for this kind of features from Xamarin-Forms-Labs called Camera.


    UPDATE (Shared Project solution)

    As requested in the comments, to use this in a Shared Project instead of PCL we could do this.

    1 - Place the IPhotoInterface in the Shared Project.

    2 - Implement the interface in Android/iOS project:

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

    3 - Use it in the Shared Project:

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

    NOTE: shared_native is the namespace of my solution and Droid/iOS are the projects for Android and iOS.

    0 讨论(0)
提交回复
热议问题