通常情况下,我们的程序需要从服务器读取图片,但如果需要不止一次读取某一张图片的话,就需要做本地缓存了,这样既为用户省一点流量,又能显得你的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. SQL Server代理(1/12):配置和概况

    SQL Server代理是所有实时数据库的核心.代理有很多不明显的用法,因此系统的知识,对于开发人员还是DBA都是有用的.这系列文章会通俗介绍它的很多用法. SQL Server代理是SQL Serv ...

  2. 高性能Web系统设计方案(初稿目录),支持者进

    第一部分 客户端篇 1.压缩js.css,将js的引入放在</html>之前; 2.合并一个页面下的js/css文件,压缩传输.(SquishIt) 相关博文 3.ajax技术应用.aja ...

  3. qml基础学习 基础概念

    一.概括 学习qt已有2年多的时间,从qt4.7开始使用直到现在正在使用的qt5.6,基本都在windows机器上做开发.最近有意向看了下qt的qml部分,觉着还是挺不错的,毕竟可以做嵌入式移动端产品 ...

  4. JavaScript的setTimeout和setInterval的深入理解

    发表过一片博客<跟着我用JavaScript写计时器>,比较基础.....有网友说应该写一下setTimeout的原理和机制,嗯,今天就来写一下吧: 直奔主题:setTimeout和set ...

  5. 关于MVC中模型model的验证问题

    今天在做项目练习的时候发现,MVC中使用自带的模型验证时会提前显示在界面上,比如下面所示: 这是什么原因了,是因为我在表示get请求的action里面返回了其界面所显示使用的model,我们知道mvc ...

  6. Guid算法与标识列(自动增长字段)在表中的应用

    <<1>>int(bigint)+标识列(自动增长字段) 用标识列实现字段自增可以避免并发等问题.不需开发人员自己控制自增,用标识列的字段在Insert的时候不用指定主键的值. ...

  7. 十五个常用的jquery代码段

    十五个常用的jquery代码段 回到顶部按钮 通过使用 jQuery 中的 animate 和 scrollTop 方法,你无需插件便可创建一个简单地回到顶部动画: 1 // Back to top ...

  8. 上传文件被nginx全部缓存的问题

    nginx采用1.5.6. 后端采用nodejs+formidable的方式接受上传文件,本问题的对应与采用什么样的后端没太大关系,这里只是交代一下. 问题: 在前端页面上将文件上传,nginx没有将 ...

  9. java的各种类型转换汇总

    java类型转换 Integer String Long Float Double Date 1如何将字串 String 转换成整数 int? A. 有两个方法: 1). int i = Intege ...

  10. 一个十年java程序员的心得

    展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告 走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然时代在变化,但是很可能你也会走我已经做过的1 ...