Reputation: 4559
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.
Image.Source
takes object of ImageSource
type. I tried ImageSource.FromFile
, ImageSource.FromStream
and even ImageSource.FromUri
. The result is always that image is not displayed (no error or exception). I validated that the path to file is correct by first opening it with File.Open
one line above.
What is the correct way of displaying pictures from normal storage, not from assets/resources/etc?
This code does not work:
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);
Upvotes: 5
Views: 10199
Reputation: 7840
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.
Upvotes: 5