从隔离存储中保存和加载图像(Windows Phone)

时间:2012-07-16 07:40:15

标签: c# silverlight windows-phone-7 silverlight-4.0

我在这个链接上找到了一个非常有用的类:images caching - 这有助于我为缓存图像制作逻辑。但就我而言,我有这个:

 private void DetailView_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                                   SaveAndLoadImage(feedItem);


            }

在这种方法中,我从孤立存储中保存并加载图像。但由于某些权限,我无法通过imidiately加载文件(在IsolatedStorageFileStream上不允许操作。)。如何更正我的逻辑以立即保存和加载图像?

  public void SaveAndLoadImage(MediaItemViewModel curItem)
            {
                string url = string.Empty;
                if (!string.IsNullOrEmpty(curItem.ThumbUrl))
                {
                    url = curItem.ThumbUrl;
                }
                if ((string.IsNullOrEmpty(curItem.ThumbUrl)) && (!string.IsNullOrEmpty(curItem.MediaUrl)))
                {
                    url = curItem.MediaUrl;
                }
                if ((!string.IsNullOrEmpty(url)) && (CacheImageFile.GetInstance().IsOnStorage(new Uri(url)) == false))
                {
                    CacheImageFile.DownloadFromWeb(new Uri(url));

                }

                    curItem.ImageSource = CacheImageFile.ExtractFromLocalStorage(new Uri(url)) as BitmapImage;

            }

3 个答案:

答案 0 :(得分:3)

看看下面的链接

http://www.windowsphonegeek.com/tips/All-about-WP7-Isolated-Storage---Read-and-Save-Images

用于从隔离存储中加载图像。使用流

BitmapImage bi = new BitmapImage();

            using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream fileStream = myIsolatedStorage.OpenFile("logo.jpg", FileMode.Open, FileAccess.Read))
                {
                    bi.SetSource(fileStream);
                    this.img.Height = bi.PixelHeight;
                    this.img.Width = bi.PixelWidth;
                }
            }
            this.img.Source = bi;

答案 1 :(得分:1)

您正在从Web异步获取映像,但立即转到下一行以读取尚未写入隔离存储的文件。这就是导致你例外的原因。

您可以尝试使用ManualResetEvent编辑在github上找到的缓存库。请注意,您必须在另一个线程上进行方法调用!

例如:

public class CacheImageFileConverter : IValueConverter
{
    ...
    private static ManualResetEvent mre = new ManualResetEvent(true);

    private static object DownloadFromWeb(Uri imageFileUri)
    {
        mre.Reset();
        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();
            mre.Set();
        };
        m_webClient.OpenReadAsync(imageFileUri);
        return bm;
    }

    private static object ExtractFromLocalStorage(Uri imageFileUri)
    {
        mre.WaitOne();
        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;
        }
    }
    .... other methods
}

请注意使用Reset,Set和WaitOne进行信号传输。

答案 2 :(得分:1)

您可以使用JetImageLoader,我为应用程序创建它,我们需要加载,缓存并显示大量徽标,图标等。

它可以用作绑定转换器,所以你甚至不应该改变你的代码!只需更新您的XAML!

请查看samples in repository,你会喜欢它;)

功能

  • 在磁盘上缓存
  • 内存缓存
  • 完全异步
  • 可用作绑定转换器或以编程方式从您的代码中
  • 完全开源,分叉并改进它!

以下是示例:

<Image Source="{Binding ImageUrl, Converter={StaticResource MyAppJetImageLoaderConverter}}"/>

P.S。对不起,我从另一个问题中复制了我的答案,但是在Windows手机上的图像缓存是一个很大的问题,我想分享我的解决方案,所以每个人都可以使用它并改进开发者社区