通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的APP很快。

  假如你已经知道了某一张图片的地址,那么第一件事就是要把这张图片下载下来;当然如果是一次性读取的话,可以直接把图片地址给Image控件或者给Bitmapimage对象(实际上这二者是没有去别的),但这无法存到本地,只作为显示用;但是我们要做的是保存到本地,这样肯定是不行的。现在我们就要用到HTTP的东西了,请看下面的代码:

 async static public Task<IInputStream> GetStreamAsync(string url)
{ httpClient = new HttpClient();
var response = await httpClient.GetInputStreamAsync(new Uri(url));
return response;
} async static public Task<IBuffer> GetBufferAsync(string url)
{ httpClient = new HttpClient(); var ResultStr = await httpClient.GetBufferAsync(new Uri(url));
return ResultStr;
}

这两个静态方法分别获取url地址的buffer数据和输入流。有了buffer或者stream之后就可以进行下一步-保存。

  当我们下载完成后,首先要做的很有可能是先显示出来,然后再保存,所以先把数据写入到图片对象中:

这里有两种方法:

1.WriteableBitmap

 protected async Task<WriteableBitmap> GetWriteableBitmapAsync(string url)
{
try
{
IBuffer buffer = await GetBufferAsync(url);
if (buffer != null)
{
BitmapImage bi = new BitmapImage();
WriteableBitmap wb = null; Stream stream2Write;
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{ stream2Write = stream.AsStreamForWrite(); await stream2Write.WriteAsync(buffer.ToArray(), , (int)buffer.Length); await stream2Write.FlushAsync();
stream.Seek(); await bi.SetSourceAsync(stream); wb = new WriteableBitmap(bi.PixelWidth, bi.PixelHeight);
stream.Seek();
await wb.SetSourceAsync(stream); return wb;
}
}
else
{
return null;
}
}
catch
{
return null;
}
}

2.SoftwareBitmap

public async Task<SoftwareBitmap> GetSoftwareBitmapAsync(string url)
{
try
{
IInputStream inputStream = await GetSteramAsync(url);
IRandomAccessStream memStream = new InMemoryRandomAccessStream();
await RandomAccessStream.CopyAsync(inputStream, memStream);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memStream);
SoftwareBitmap sb = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
return sb;
}
catch
{
return null;
}
}

这两种都可以作为展示图像的数据源,其中WriteableBitmap可以直接给Image.Source , SoftwareBitmap这需要转为SoftwareBitmap:

          SoftwareBitmapSource sbs = new SoftwareBitmapSource();
sbs.SetBitmapAsync(sb);

接下来就是保存了:WriteableBitmap:

 public async Task SaveImageAsync(WriteableBitmap image, string filename)
{
try
{
if (image == null)
{
return;
}
Guid BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
if (filename.EndsWith("jpg"))
BitmapEncoderGuid = BitmapEncoder.JpegEncoderId;
else if (filename.EndsWith("png"))
BitmapEncoderGuid = BitmapEncoder.PngEncoderId;
else if (filename.EndsWith("bmp"))
BitmapEncoderGuid = BitmapEncoder.BmpEncoderId;
else if (filename.EndsWith("tiff"))
BitmapEncoderGuid = BitmapEncoder.TiffEncoderId;
else if (filename.EndsWith("gif"))
BitmapEncoderGuid = BitmapEncoder.GifEncoderId;
var folder = await _local_folder.CreateFolderAsync("images_cache", CreationCollisionOption.OpenIfExists);
var file = await folder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting); using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoderGuid, stream);
Stream pixelStream = image.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, , pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore,
(uint)image.PixelWidth,
(uint)image.PixelHeight,
96.0,
96.0,
pixels);
await encoder.FlushAsync();
}
}
catch
{ }
}
public async Task WriteToFileAsync(StorageFolder folder,SoftwareBitmap sb,string fileName)
{ if (sb != null)
{
// save image file to cache
StorageFile file = await folder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);
using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
encoder.SetSoftwareBitmap(sb);
await encoder.FlushAsync();
}
}
}

怎么样,是不是很简单?

UWP开发中两种网络图片缓存方法的更多相关文章

  1. 说一说Web开发中两种常用的分层架构及其对应的代码模型

    昨天妹子让我帮她解决个问题,本以为可以轻松搞定,但是打开他们项目的一瞬间,我头皮发麻.本身功能不多的一个小项目,解决方案里竟然有几十个类库.仅仅搞明白各个类库的作用,代码层次之间的引用关系就花了一个多 ...

  2. Python中两种处理错误方法的比较

    我所说的处理错误的方法,其实是try:,except和raise这两种. 首先抛出一个实例, dictt={'a':1,'b':2,'c':3} try: if dictt['d']>1: #字 ...

  3. Cesium 中两种添加 model 方法的区别

    概述 Cesium 中包含两种添加 model 的方法,分别为: 通过 viewer.entities.add() 函数添加 通过 viewer.scene.primitives.add() 函数添加 ...

  4. Mat中两种像素遍历方法比较

    小白,入门中,不足其指正.刚刚接触opencv,从一个Matlab风格的编程环境突然跳转到C++,实在有些不适.单就pixels scanning花了好长时间研究.opencv-tutorials给出 ...

  5. python中两种拷贝目录方法的比较

    首先是用python自己的api: shutil.copytree('./build/tested/doc', './build/tested/build/doc') 优点是改变平台时不需要修改代码, ...

  6. JAVA 中两种判断输入的是否是数字的方法__正则化_

    JAVA 中两种判断输入的是否是数字的方法 package t0806; import java.io.*; import java.util.regex.*; public class zhengz ...

  7. jsp中两种include的区别【转】

    引用文章:http://www.ibm.com/developerworks/cn/java/j-jsp04293/ http://www.cnblogs.com/lazycoding/archive ...

  8. IOS开发-几种截屏方法

    IOS开发-几种截屏方法 1.        UIGraphicsBeginImageContextWithOptions(pageView.page.bounds.size, YES, zoomSc ...

  9. GET和POST两种基本请求方法(转自博主--在途中#)

    GET和POST两种基本请求方法的区别 GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过req ...

随机推荐

  1. 阅读《LEARNING HARD C#学习笔记》知识点总结与摘要系列文章索引

    从发表第一篇文章到最后一篇文章,时间间隔有整整一个月,虽只有5篇文章,但每一篇文章都是我吸收<LEARNING HARD C#学习笔记>这本书的内容要点及网上各位大牛们的经验,没有半点废话 ...

  2. LeetCode - Populating Next Right Pointers in Each Node II

    题目: Follow up for problem "Populating Next Right Pointers in Each Node". What if the given ...

  3. When using SqlDependency without providing an options value, SqlDependency.Start() must be called prior to execution of a command added to the SqlDependency instance.

    在调试SignalR程序时,提示一个异常:When using SqlDependency without providing an options value, SqlDependency.Star ...

  4. IBM和传统IT的沦落

    传统IT厂商沦落已经成为一种趋势.不仅仅是在中国去IOE的大背景下,在全球范围内,这些曾经盛极一时的IT大鳄也在衰落.作为一个在IBM服务了将近14年的老员工,我想浅谈一下IBM以及整个传统IT行业的 ...

  5. 微信开发中遇到“当前页面的url未注册”问题

    在公众号后台设置支付授权目录,完全按照规则去设定的,但是在实际测试中会出现“当前页面的url未注册”的问题,反复确认后发现目录并没有问题,唯一的区别就是大小写不同. 但是一般url不都是不区分大小写的 ...

  6. webstorage[html5的本地数据处理]

    1.webStorage是什么? webStorage是html5中用于本地化存储的一种方式,而在之前呢我们是用cookie的存储方式处理; 2.那它们之间的区别是什么? Ⅰ.cookie存在的问题: ...

  7. Error Code: 1175.You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column.

    在MySQL Workbench里面使用SQL语句: delete from 表名 提示出错: Error Code: 1175.You are using safe update mode and ...

  8. 【Java每日一题】20161115

    package Nov2016; import java.io.Serializable; public class Ques1115 implements Serializable{ private ...

  9. Docker: adding a file from a parent directory

    17down votefavorite 4 In my Dockerfile I've got : ADD ../../myapp.war /opt/tomcat7/webapps/ That fil ...

  10. Java并发编程:Timer和TimerTask(转载)

    Java并发编程:Timer和TimerTask(转载) 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer ...