Fonte di immagini e memorizzazione nella cache

Io uso il seguente codice per mostrare le immagini da un server web:

 

L’immagine viene scaricata automaticamente e presumo che ci sia anche del caching basato sull’URL.

Il mio problema è che quando l’app non è in linea, le immagini presumibilmente memorizzate nella cache non vengono visualizzate.

C’è un modo per cambiare il comportamento della cache, in modo che le immagini vengano caricate anche quando non c’è una rete disponibile? Puntatori alla documentazione relativa al caching sarebbero molto utili.

BitmapImage memorizza automaticamente nella cache le immagini remote per impostazione predefinita. È preferibile utilizzare in combinazione con CreateOptions="BackgroundCreation" per le migliori prestazioni.

      

Questo post del blog MSDN , vecchio ma ancora pertinente, elenca e spiega tutte le CreationOptions e quella memorizzazione nella cache è automatica nella maggior parte delle modalità.

Io uso queste opzioni per visualizzare molte notizie con immagini e funziona bene. Posso caricare l’elenco degli articoli, uscire dall’app e triggersre la Modalità aereo su On, quindi avviare una nuova istanza dell’app e le immagini continuano a caricarsi.

Approccio manuale

Se desideri controllare tu stesso la cache e memorizzare le risorse HTTPS, ci sono alcuni buoni esempi …

  • ImgCache dall’app iFixit
  • Convertitore di valori che scarica e salva le immagini
  • PersistentImageCache dal Kawagoe Toolkit (potrebbe essere necessario un aggiornamento per funzionare con WP 7.5 o 8)

Ho una soluzione per te. È JetImageLoader , l’ho creato per l’applicazione, dove dobbiamo caricare, memorizzare e mostrare una grande quantità di loghi, icone e così via.

Può essere usato come convertitore di binding, quindi non dovresti nemmeno cambiare il tuo codice! Aggiorna i tuoi XAML!

Per favore, controlla gli esempi nel repository , ti piacerà;)

Caratteristiche:

  • Memorizzazione nella cache sul disco
  • Memorizzazione nella memoria cache
  • Completamente asincrono
  • Disponibile come convertitore di binding o programmaticamente dal tuo codice
  • Completamente open source, fork e miglioralo!

Ecco l’esempio:

  

Non penso che ci sia un modo per farlo, ma potresti salvare le immagini in IsolatedStorage e utilizzare un convertitore che controlla la disponibilità di Internet e restituisce l’URL online o offline.

Una rapida ricerca ha prodotto ciò che potrebbe essere esattamente quello che stai cercando (è compatibile con Windows Phone 7 e potrebbe non essere la soluzione migliore per Windows Phone 8)

La mia soluzione: (salva l’immagine dal web alla memoria locale e associa l’immagine salvata alla pagina)

XAML

        

DataModel

 public class DataModel_ListOfEvents { public DataModel_ListOfEvents(String img_thumb) { this.Img_Thumb = new NotifyTaskCompletion(JsonCached.ImageFromCache2(img_thumb)); } public NotifyTaskCompletion Img_Thumb { get; private set; } } public sealed class SampleData_ListOfEvents { private static SampleData_ListOfEvents _sampleDataSource = new SampleData_ListOfEvents(); private ObservableCollection _items = new ObservableCollection(); public ObservableCollection Items { get { return this._items; } } } 

Magia

 public class JsonCached { public static async Task ImageFromCache2(string path) { int ru = path.IndexOf(".ru") + 4;// TODO: .com .net .org string new_path = path.Substring(ru).Replace("/", "\\"); StorageFolder localFolder = ApplicationData.Current.LocalFolder; try { Stream p = await localFolder.OpenStreamForReadAsync(new_path); p.Dispose(); System.Diagnostics.Debug.WriteLine("From cache"); return localFolder.Path + "\\" + new_path; } catch (FileNotFoundException) { } catch (Exception e) { System.Diagnostics.Debug.WriteLine("{0}", e.Message); } StorageFile storageFile = await localFolder.CreateFileAsync(new_path, CreationCollisionOption.OpenIfExists); Uri Website = new Uri(path); HttpClient http = new HttpClient(); // TODO: Check connection. Return message on fail. System.Diagnostics.Debug.WriteLine("Downloading started"); byte[] image_from_web_as_bytes = await http.GetByteArrayAsync(Website); MakeFolders(localFolder, path.Substring(ru)); Stream outputStream = await storageFile.OpenStreamForWriteAsync(); outputStream.Write(image_from_web_as_bytes, 0, image_from_web_as_bytes.Length); outputStream.Position = 0; System.Diagnostics.Debug.WriteLine("Write file done {0}", outputStream.Length); outputStream.Dispose(); return localFolder.Path + "\\" + new_path; } private static async void MakeFolders(StorageFolder localFolder, string path) { //pics/thumbnail/050/197/50197442.jpg int slash = path.IndexOf("/"); if (slash < = 0) // -1 Not found return; string new_path = path.Substring(0, slash); StorageFolder opened_folder = await localFolder.CreateFolderAsync(new_path, CreationCollisionOption.OpenIfExists); string very_new_path = path.Remove(0, new_path.Length + 1); MakeFolders(opened_folder, very_new_path); } } 

NotifyTaskCompletion

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.ComponentModel; namespace App2.NotifyTask { public sealed class NotifyTaskCompletion : INotifyPropertyChanged { public NotifyTaskCompletion(Task task) { Task = task; if (!task.IsCompleted) { var _ = WatchTaskAsync(task); } } private async Task WatchTaskAsync(Task task) { try { await task; } catch { } var propertyChanged = PropertyChanged; if (propertyChanged == null) return; propertyChanged(this, new PropertyChangedEventArgs("Status")); propertyChanged(this, new PropertyChangedEventArgs("IsCompleted")); propertyChanged(this, new PropertyChangedEventArgs("IsNotCompleted")); if (task.IsCanceled) { propertyChanged(this, new PropertyChangedEventArgs("IsCanceled")); } else if (task.IsFaulted) { propertyChanged(this, new PropertyChangedEventArgs("IsFaulted")); propertyChanged(this, new PropertyChangedEventArgs("Exception")); propertyChanged(this, new PropertyChangedEventArgs("InnerException")); propertyChanged(this, new PropertyChangedEventArgs("ErrorMessage")); } else { propertyChanged(this, new PropertyChangedEventArgs("IsSuccessfullyCompleted")); propertyChanged(this, new PropertyChangedEventArgs("Result")); } } public Task Task { get; private set; } public TResult Result { get { return (Task.Status == TaskStatus.RanToCompletion) ? Task.Result : default(TResult); } } public TaskStatus Status { get { return Task.Status; } } public bool IsCompleted { get { return Task.IsCompleted; } } public bool IsNotCompleted { get { return !Task.IsCompleted; } } public bool IsSuccessfullyCompleted { get { return Task.Status == TaskStatus.RanToCompletion; } } public bool IsCanceled { get { return Task.IsCanceled; } } public bool IsFaulted { get { return Task.IsFaulted; } } public AggregateException Exception { get { return Task.Exception; } } public Exception InnerException { get { return (Exception == null) ? null : Exception.InnerException; } } public string ErrorMessage { get { return (InnerException == null) ? null : InnerException.Message; } } public event PropertyChangedEventHandler PropertyChanged; } } 

Puoi anche utilizzare FFImageLoading ( https://github.com/molinch/FFImageLoading/ )

Caratteristiche

  • Supporto Xamarin.iOS (min iOS 7), Xamarin.Android (minimo Android 4), Xamarin.Forms e Windows (WinRT, UWP)
  • Memorizzazione nella cache del disco e della memoria
  • Deduplicazione di richieste di download / caricamento simili
  • Errore e caricamento supporto segnaposto
  • Le immagini possono essere ridimensionate automaticamente alla dimensione specificata (meno utilizzo della memoria)
  • Supporto WebP
  • Supporto per le animazioni di caricamento delle immagini in dissolvenza
  • Puoi riprovare a scaricare immagini (RetryCount, RetryDelay)
  • Su Android la trasparenza è disabilitata per impostazione predefinita (configurabile). Salva il 50% della memoria
  • Supporto per le trasformazioni
    • BlurredTransformation
    • CircleTransformation, RoundedTransformation, CornersTransformation
    • ColorSpaceTransformation, GrayscaleTransformation, SepiaTransformation
    • FlipTransformation
    • Supporta trasformazioni personalizzate (implementazioni ITransformation della piattaforma nativa)

È semplice come:

   

Esempi di progetti qui: https://github.com/molinch/FFImageLoading/tree/master/samples/