Skip to content

Instantly share code, notes, and snippets.

@chandermani
Created May 13, 2012 12:58
Show Gist options
  • Save chandermani/2688372 to your computer and use it in GitHub Desktop.
Save chandermani/2688372 to your computer and use it in GitHub Desktop.
Windows Phone Image Caching Converter
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Data;
using System.IO.IsolatedStorage;
using System.IO;
using System.Windows.Media.Imaging;
namespace Util.Converters
{
/// <summary>
/// Caches the image that gets downloaded as part of Image control Source property.
/// </summary>
public class CacheImageFileConverter : IValueConverter
{
private static IsolatedStorageFile _storage = IsolatedStorageFile.GetUserStoreForApplication();
private const string imageStorageFolder = "TempImages";
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string path = value as string;
if (String.IsNullOrEmpty(path)) return null;
Uri imageFileUri = new Uri(path);
if (imageFileUri.Scheme == "http" || imageFileUri.Scheme == "https")
{
if (!Phone.GetIsNetworkAvailable())
{
if (_storage.FileExists(GetFileNameInIsolatedStorage(imageFileUri)))
{
return ExtractFromLocalStorage(imageFileUri);
}
else
{
return LoadDefaultIfPassed(imageFileUri, (parameter ?? string.Empty).ToString());
}
}
else
{
return DownloadFromWeb(imageFileUri);
}
}
else
{
BitmapImage bm = new BitmapImage(imageFileUri);
return bm;
}
}
private static object LoadDefaultIfPassed(Uri imageFileUri, string defaultImagePath)
{
string defaultImageUri = (defaultImagePath ?? string.Empty).ToString();
if (!string.IsNullOrEmpty(defaultImageUri))
{
BitmapImage bm = new BitmapImage(new Uri(defaultImageUri,UriKind.Relative)); //Load default Image
return bm;
}
else
{
BitmapImage bm = new BitmapImage(imageFileUri);
return bm;
}
}
private static object DownloadFromWeb(Uri imageFileUri)
{
WebClient m_webClient = new WebClient(); //Load from internet
BitmapImage bm = new BitmapImage();
m_webClient.OpenReadCompleted += (o, e) =>
{
if (e.Error != null || e.Cancelled) return;
WriteToIsolatedStorage(IsolatedStorageFile.GetUserStoreForApplication(), e.Result, GetFileNameInIsolatedStorage(imageFileUri));
bm.SetSource(e.Result);
e.Result.Close();
};
m_webClient.OpenReadAsync(imageFileUri);
return bm;
}
private static object ExtractFromLocalStorage(Uri imageFileUri)
{
string isolatedStoragePath = GetFileNameInIsolatedStorage(imageFileUri); //Load from local storage
using (var sourceFile = _storage.OpenFile(isolatedStoragePath, FileMode.Open, FileAccess.Read))
{
BitmapImage bm = new BitmapImage();
bm.SetSource(sourceFile);
return bm;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
private static void WriteToIsolatedStorage(IsolatedStorageFile storage, System.IO.Stream inputStream, string fileName)
{
IsolatedStorageFileStream outputStream = null;
try
{
if (!storage.DirectoryExists(imageStorageFolder))
{
storage.CreateDirectory(imageStorageFolder);
}
if (storage.FileExists(fileName))
{
storage.DeleteFile(fileName);
}
outputStream = storage.CreateFile(fileName);
byte[] buffer = new byte[32768];
int read;
while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{
outputStream.Write(buffer, 0, read);
}
outputStream.Close();
}
catch
{
//We cannot do anything here.
if (outputStream != null) outputStream.Close();
}
}
/// <summary>
/// Gets the file name in isolated storage for the Uri specified. This name should be used to search in the isolated storage.
/// </summary>
/// <param name="uri">The URI.</param>
/// <returns></returns>
public static string GetFileNameInIsolatedStorage(Uri uri)
{
return imageStorageFolder + "\\" + uri.AbsoluteUri.GetHashCode() + ".img";
}
}
}
@rodmanwu
Copy link

using this code will throw TypeInitializationException

problem comes from :
private static IsolatedStorageFile _storage = IsolatedStorageFile.GetUserStoreForApplication();

i change this to:
private static IsolatedStorageFile _storage;

    public CacheImageFileConverter()
    {
        try
        {
            if (_storage == null)
            {
                _storage = IsolatedStorageFile.GetUserStoreForApplication();
            }
        }
        catch (IsolatedStorageException e)
        {
            Debug.WriteLine(e);
        }
    }

it seems fix the problom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment