欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片

程序员文章站 2022-03-23 11:52:55
作为Web App访问远程图片是经常的遇到功能,Wp本身提供了Image 很好的支持通过图片的Uri显示图片 public ImageSource Source { get; s...

作为Web App访问远程图片是经常的遇到功能,Wp本身提供了Image 很好的支持通过图片的Uri显示图片
public ImageSource Source { get; set; }

<Image Source="http://up.2cto.com/2012/0301/20120301094720431.png" />
为了减少网络流量,需要将图片缓存到本地数据存储中。复习一下WP的本地数据存储:
 
Windows Phone 本地数据存储
Windows Phone 应用程序可以使用独立存储将数据储存到手机本地。应用程序可以通过三种方式储存数据:
1. 设置:使用 IsolatedStorageSettings 类将数据存储为键/值对。
2. 文件和文件夹:使用 IsolatedStorageFile 类存储文件和文件夹。
3. 本地数据库:7.1新增,只能支持LINQ TO SQL ,不能写SQL语句。
 
本地存储图片
首先图片应该选择IsolatedStorageFile来存储:
WP提供了一个叫IsolatedStorageFileStream的Stream和FileStream操作一样
using (var fileStream = isolatedStorageFile.OpenFile(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
       stream.CopyTo(fileStream);
}

 
 
缓存的思路
WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片


 

现在是思路是首先检查是否被缓存里,首先定义一个公用的缓存文件夹,在静态构造函数中创建文件夹
private const string CacheDirectory = "CachedImages";
       
        static StorageCachedImage()
        {

            //创建缓存目录
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isolatedStorageFile.DirectoryExists(CacheDirectory))
                {
                    isolatedStorageFile.CreateDirectory(CacheDirectory);
                }
            }
        }
 

然后将Url转换成文件名,我的方法比较简单直接替换’/’符号。使用FileExists判断文件是否存在
//文件路径
filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));

/// <summary>
       /// 打开缓存源
       /// </summary>
       private void OpenCatchSource()
       {
           bool exist;
           using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
           {
               exist = isolatedStorageFile.FileExists(filePath);
           }
           if (exist)
           {
               SetCacheStreamSource();
           }
           else
           {
               SetWebStreamSource();
           }
       }
 

如果没有缓存则通过Uri下载图片并保存到IsolatedStorageFile。
使用httpWebRequest实现下载,使用IsolatedStorageFileStream保存图片
/// <summary>
       /// 下载Uri中的图片
       /// </summary>
       private void SetWebStreamSource()
       {
           var httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
           httpWebRequest.AllowReadStreamBuffering = true;
           httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
       }

       /// <summary>
       /// 下载回调
       /// </summary>
       /// <param name="asyncResult"></param>
       private void ResponseCallBack(IAsyncResult asyncResult)
       {
           var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
           if(httpWebRequest == null)return;
           try
           {
               var response = httpWebRequest.EndGetResponse(asyncResult);
               using(var stream = response.GetResponseStream())
               using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
               using (var fileStream = isolatedStorageFile.OpenFile
                   (filePath, FileMode.OpenOrCreate, FileAccess.Write))
               {
                   stream.CopyTo(fileStream);//保存到本地
               }
               Dispatcher.BeginInvoke(SetCacheStreamSource);
           }
           catch(Exception err)
           {
               Debug.WriteLine(err.Message);
           }
       }
 

保存到本地后下载,用IsolatedStorageFileStream打开本地图像流,并通过父类的SetSource设置图片流。
private void SetCacheStreamSource()
       {
           using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
           using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
           {
               SetSource(stream);
           }

 
完整代码如下:

 using System;
using System.Diagnostics;
using System.IO;
using System.IO.IsolatedStorage;
using System.Net;
using System.Windows.Media.Imaging;

namespace KimiStudio.Controls
{
    /// <summary>
    /// 独立存储缓存的图片源
    /// </summary>
    public sealed class StorageCachedImage : BitmapSource
    {
        private readonly Uri uriSource;
        private readonly string filePath;
        private const string CacheDirectory = "CachedImages";
       
        static StorageCachedImage()
        {

            //创建缓存目录
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isolatedStorageFile.DirectoryExists(CacheDirectory))
                {
                    isolatedStorageFile.CreateDirectory(CacheDirectory);
                }
            }
        }

        /// <summary>
        /// 创建一个独立存储缓存的图片源
        /// </summary>
        /// <param name="uriSource"></param>
        public StorageCachedImage(Uri uriSource)
        {
            this.uriSource = uriSource;

            //文件路径
            filePath = Path.Combine(CacheDirectory, uriSource.AbsolutePath.TrimStart('/').Replace('/', '_'));
            OpenCatchSource();
        }

        /// <summary>
        /// 打开缓存源
        /// </summary>
        private void OpenCatchSource()
        {
            bool exist;
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            {
                exist = isolatedStorageFile.FileExists(filePath);
            }
            if (exist)
            {
                SetCacheStreamSource();
            }
            else
            {
                SetWebStreamSource();
            }
        }

        /// <summary>
        /// 设置缓存流到图片
        /// </summary>
        private void SetCacheStreamSource()
        {
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
            using (var stream = isolatedStorageFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
            {
                SetSource(stream);
            }
        }

        /// <summary>
        /// 下载Uri中的图片
        /// </summary>
        private void SetWebStreamSource()
        {
            var httpWebRequest = (HttpWebRequest)WebRequest.Create(uriSource);
            httpWebRequest.AllowReadStreamBuffering = true;
            httpWebRequest.BeginGetResponse(ResponseCallBack, httpWebRequest);
        }

        /// <summary>
        /// 下载回调
        /// </summary>
        /// <param name="asyncResult"></param>
        private void ResponseCallBack(IAsyncResult asyncResult)
        {
            var httpWebRequest = asyncResult.AsyncState as HttpWebRequest;
            if(httpWebRequest == null)return;
            try
            {
                var response = httpWebRequest.EndGetResponse(asyncResult);
                using(var stream = response.GetResponseStream())
                using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                using (var fileStream = isolatedStorageFile.OpenFile
                    (filePath, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    stream.CopyTo(fileStream);
                }
                Dispatcher.BeginInvoke(SetCacheStreamSource);
            }
            catch(Exception err)
            {
                Debug.WriteLine(err.Message);
            }
        }
    }

  
}

 
测试
定义一个Image
Uri uriSource = new Uri(@”http://up.2cto.com/2012/0301/20120301094720431.png”);
image1.ImageSource = new StorageCachedImage(uriSource);
 
用IsoStoreSpy查看(这里是我APP实际的图)

  WP7应用开发笔记 继承BitmapSource并使用独立存储来缓存远程的图片

 


摘自 Kiminozo's Tech Blog