2016-06-11 5 views
3

Ich habe ein Bild von Artikel im externen Speicher (die Absicht in meiner App gespeichert wurde). Ich möchte dieses Bild in meinem freigegebenen Projekt in Image anzeigen.Set Bild.Quelle zu Datei in externen Speicher in Xamarin.Forms

Image.Source nimmt Objekt von ImageSource Typ. Ich versuchte ImageSource.FromFile, ImageSource.FromStream und sogar . Das Ergebnis ist immer, dass das Bild nicht angezeigt wird (kein Fehler oder Ausnahme). Ich habe überprüft, dass der Pfad zur Datei korrekt ist, indem ich ihn zuerst mit File.Open eine Zeile oben öffne.

Was ist die richtige Art, Bilder aus dem normalen Speicher anzuzeigen, nicht aus Assets/Ressourcen/etc?

Dieser Code nicht funktioniert:

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); 
+0

Ihre Anwendung ist nur für Android? – jzeferino

+0

@jzeferino Zuerst ja. Aber ich glaube, dass auch für iOS, wenn ich diesen Pfad von meiner eigenen Anwendung bekomme, dann für iOS Version auch korrekt und lesbar ist. – Episodex

+0

In der endgültigen Version möchte ich die Bilder im privaten Ordner der Anwendung, nicht im externen Speicher speichern. So kann auch die Lösung beispielsweise von "Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)" – Episodex

Antwort

4

Ihre Xamarin PCL Formulare nicht wissen, was es ist ein URI von Android beacuse seine Plattform spezifisch, so:

ImageSource.FromFile(path); 

wird nicht Arbeit.

In diesem Fall behandeln Sie plattformspezifische Funktionen, das Laden eines Bildes von Android. Ich schlage vor, diesen Ansatz:

eine Schnittstelle auf Xamarin Erstellen von Formularen PCL wie:

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

dann in Android Sie diese Schnittstelle implementieren und die Umsetzung in DependencyService registrieren:

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

Im Xamarin Formulare PCL-Code erhalten das Bild:

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

Für weitere Details können Sie this konsultieren.

HINWEIS1: Dies funktioniert auf iOS, wenn Sie auch die Schnittstelle IPhoto implementieren.

HINWEIS2: Es gibt eine hilfreiche Bibliothek für diese Art von Funktionen von Xamarin-Forms-Labs namens Camera.


UPDATE (Geteilt Projektlösung)

Wie in den Kommentaren aufgefordert, diese anstelle von PCL in einem freigegebenen Projekt verwenden wir dies tun könnte.

1 - Platzieren Sie die IPhotoInterface im freigegebenen Projekt.

2 - Umsetzung der Schnittstelle in Android/iOS-Projekt:

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

3 - Verwenden Sie es im Shared-Projekt:

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

HINWEIS: shared_native ist der Namespace meiner Lösung und Droid/iOS werden die Projekte für Android und iOS.

+0

lesen Danke! Ich werde das in zwei Stunden versuchen, aber ich benutze geteilte Projekte statt PCL. Ich hoffe es wird auch funktionieren. – Episodex

+0

Warum verwenden Sie ein gemeinsames Projekt? Wenn Sie Probleme haben, lassen Sie es mich bitte wissen. Da Sie freigegebene Projekte verwenden, können Sie dies mit einem #ifdef tun. Ich bin der Meinung, dass Sie PCL verwenden sollten. – jzeferino

+0

Ich untersuchte beide Ansätze und das geteilte Projekt schien mir angenehmer. Die Leute sagten auch, dass alles, was mit PCL gemacht werden kann, mit einem gemeinsamen Projekt gemacht werden kann. Ich hoffe es ist wahr :). Das Wechseln zu PCL ist eine Option, aber nur, wenn der Ansatz für gemeinsam genutzte Projekte vollständig fehlschlägt. Wenn Sie Zeit haben, #ifdef Version zu Ihrer Antwort hinzuzufügen, würde ich sehr schätzen :). – Episodex

Verwandte Themen