2019-9-2-win10-uwp-存放网络图片到本地
| title | author | date | CreateTime | categories |
|---|---|---|---|---|
|
win10 uwp 存放网络图片到本地
|
lindexi
|
2019-09-02 12:57:38 +0800
|
2018-2-13 17:23:3 +0800
|
Win10 UWP
|
有时候我们的网络很垃圾,我的的UWP要在第一次打开网络图片,就把图片存放到本地,下次可以从本地打开。
有时候用户使用的是流量网络,不能每次都联网下载。
我们不得在应用存放用户打开的图片。
这就是先把图片下载,然后显示出来,存放到本地,接着下次要使用就可以从本地获取。
最好这个和我们用户是透明,我们不知道图片在哪,是本地还是网络,只要给一个Uri就有一个图片。
这里图片我用BitmapImage,Uri是输入网络的
下载图片
图片也是和其他一样,我们可以简单用系统给的网络web下载。
我们需要输入Uri,然后把图片下载。
图片要显示,需要SetSourceAsync,他需要的参数IRandomAccessStream,而这个需要Buffer写数据,不能用byte,我开始用的System.Net.Http没有获取Buffer方法,于是我查了垃圾wr,最后用Windows.Web.Http
先获取图片
Windows.Web.Http.HttpClient http = new Windows.Web.Http.HttpClient();
IBuffer buffer = await http.GetBufferAsync(uri);
BitmapImage img = new BitmapImage();
using (IRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(buffer);
stream.Seek(0);
await img.SetSourceAsync(stream);
await StorageImageFolder(stream, uri);
return img;
}
StorageImageFolder就是保存图片
保存图片
我们需要知道一个Uri就可以拿到一个图片,但是Uri不能做文件名,于是我用md5
Uwp使用Md5,可以去看我写的文章
private static string Md5(string str)
{
HashAlgorithmProvider hashAlgorithm =
HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash cryptographic = hashAlgorithm.CreateHash();
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf8);
cryptographic.Append(buffer);
return CryptographicBuffer.EncodeToHexString(cryptographic.GetValueAndReset());
}
我们的图片存放在本地,最后放在ApplicationData.Current.LocalCacheFolder
在存放文件,RandomAccessStream需要转byte[]
private static async Task<byte[]> ConvertIRandomAccessStreamByte(IRandomAccessStream stream)
{
DataReader read = new DataReader(stream.GetInputStreamAt(0));
await read.LoadAsync((uint)stream.Size);
byte[] temp = new byte[stream.Size];
read.ReadBytes(temp);
return temp;
}
存放文件
string image = Md5(uri.AbsolutePath);
StorageFile file = await folder.CreateFileAsync(image);
await FileIO.WriteBytesAsync(file, await ConvertIRandomAccessStreamByte(stream));
从本地打开
把Uri转为图片名,打开本地文件
string name = Md5(uri.AbsolutePath);
StorageFile file = await folder.GetFileAsync(name);
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
BitmapImage img = new BitmapImage();
await img.SetSourceAsync(stream);
return img;
}
所有代码
第一次使用图片从网络打开,第二次就可以放在本地,不使用网络。
先搜索本地,本地存在就打开,不存在只好从网络打开
函数使用就是ImageStorage.GetImage(uri);
public static class ImageStorage
{
/// <summary>
/// 获取图片
/// 如果本地存在,就获取本地
/// 如果本地不存在,获取网络
/// </summary>
/// <param name="uri"></param>
/// <returns></returns>
public static async Task<BitmapImage> GetImage(Uri uri)
{
return await GetLoacalFolderImage(uri) ??
await GetHttpImage(uri);
}
/// <summary>
/// 从本地获取图片
/// </summary>
/// <param name="uri"></param>
private static async Task<BitmapImage> GetLoacalFolderImage(Uri uri)
{
StorageFolder folder = await GetImageFolder();
string name = Md5(uri.AbsolutePath);
try
{
StorageFile file = await folder.GetFileAsync(name);
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
BitmapImage img = new BitmapImage();
await img.SetSourceAsync(stream);
return img;
}
}
catch (Exception)
{
return null;
}
}
private static async Task<BitmapImage> GetHttpImage(Uri uri)
{
try
{
Windows.Web.Http.HttpClient http = new Windows.Web.Http.HttpClient();
IBuffer buffer = await http.GetBufferAsync(uri);
BitmapImage img = new BitmapImage();
using (IRandomAccessStream stream = new InMemoryRandomAccessStream())
{
await stream.WriteAsync(buffer);
stream.Seek(0);
await img.SetSourceAsync(stream);
await StorageImageFolder(stream, uri);
return img;
}
}
catch (Exception)
{
return null;
}
}
private static async Task StorageImageFolder(IRandomAccessStream stream, Uri uri)
{
StorageFolder folder = await GetImageFolder();
string image = Md5(uri.AbsolutePath);
try
{
StorageFile file = await folder.CreateFileAsync(image);
await FileIO.WriteBytesAsync(file, await ConvertIRandomAccessStreamByte(stream));
}
catch (Exception)
{
}
}
private static async Task<byte[]> ConvertIRandomAccessStreamByte(IRandomAccessStream stream)
{
DataReader read = new DataReader(stream.GetInputStreamAt(0));
await read.LoadAsync((uint)stream.Size);
byte[] temp = new byte[stream.Size];
read.ReadBytes(temp);
return temp;
}
private static async Task<StorageFolder> GetImageFolder()
{
//文件夹
string name = "image";
StorageFolder folder = null;
//从本地获取文件夹
try
{
folder = await ApplicationData.Current.LocalCacheFolder.GetFolderAsync(name);
}
catch (FileNotFoundException)
{
//没找到
folder = await ApplicationData.Current.LocalCacheFolder.
CreateFolderAsync(name);
}
return folder;
}
private static string Md5(string str)
{
HashAlgorithmProvider hashAlgorithm =
HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Md5);
CryptographicHash cryptographic = hashAlgorithm.CreateHash();
IBuffer buffer = CryptographicBuffer.ConvertStringToBinary(str, BinaryStringEncoding.Utf8);
cryptographic.Append(buffer);
return CryptographicBuffer.EncodeToHexString(cryptographic.GetValueAndReset());
}
}
Nuget安装
Nuget搜索lindexi.uwp.src.ImageStorage
命令行
Install-Package lindexi.uwp.src.ImageStorage
Microsoft.Toolkit.Uwp
当前图片缓存的功能已经合并到 Microsoft.Toolkit.Uwp 工具,不过里面已经看不到我写的代码了,所以变得更加好用
在最低版本为 16299 之后可以通过 nuget 找到 Microsoft.Toolkit.Uwp 安装,然后可以使用下面的代码判断如果图片已经保存在本地,就从本地读取图片。如果图片没有保存到本地,就从网络下载
// 图片可以保存多久的时间
ImageCache.Instance.CacheDuration = TimeSpan.FromHours(24); // 最多可以在内存存放多少张图片
ImageCache.Instance.MaxMemoryCacheCount = 100; var distantUri = new Uri("http://www.myserver.com/image.jpg"); // 如果图片没有在缓存里,将会下载图片。如果图片在缓存里,直接返回图片
var bitmapImage = await ImageCache.Instance.GetFromCacheAsync(distantUri); // 清理缓存
await ImageCache.Instance.ClearAsync();
2019-9-2-win10-uwp-存放网络图片到本地的更多相关文章
- win10 uwp 存放网络图片到本地
有时候我们的网络很垃圾,我的的UWP要在第一次打开网络图片,就把图片存放到本地,下次可以从本地打开. 有时候用户使用的是流量网络,不能每次都联网下载. 我们不得在应用存放用户打开的图片. 这就是先把图 ...
- win10 uwp 读取保存WriteableBitmap 、BitmapImage
我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap.关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说.主要说的 ...
- win10 UWP 应用设置
win10 UWP 应用设置 简单的把设置需要的,放到微软自带的LocalSettings LocalSettings.Values可以存放几乎所有数据 如果需要存放复合数据,一个设置项是由多个值组成 ...
- win10 uwp 如何开始写 uwp 程序
本文告诉大家如何创建一个 UWP 程序. 这是一系列的 uwp 入门博客,所以写的很简单 本文来告诉大家如何创建一个简单的程序 安装 VisualStudio 在开始写 UWP 需要安装 Visual ...
- win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序
本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...
- win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl
本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ...
- win10 uwp 发布旁加载自动更新
在很多企业使用的程序都是不能通过微软商店发布,原因很多,其中我之前的团队开发了很久的应用,结果发现没有用户能从微软应用商店下载所以我对应用商店没有好感.但是作为一个微软粉丝,怎么能不支持 UWP 开发 ...
- win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑
本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...
- Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App
安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...
随机推荐
- springboot中的web项目不能访问templates中的静态资源
方法1: 重新创建文件夹,配置yml文件: spring.resources.static-locations=classpath:/view/ spring.mvc.view.suffix=.htm ...
- Android之AbsoluteLayout(绝对布局)
1.属性简介 为了适配不同机型,绝对布局使用很少! android:layout_x="50dp" android:layout_y="100dp"也只有在Ab ...
- shell 的基本理解
shell 事先通过一个变量设定好了多个路径,当用户输入命令时,shell会自动到这些路径(由左向右)以此查找 与命令名称相同的可执行文件 hash 用来保存以前曾经执行过的命令,以哈希表的方式保存, ...
- js中读取json数据
1.JSON字符串转为JSON对象 var obj = eval('('+data+')');① var obj = data.praseJSON();② var obj = JSON.prase(d ...
- <爬虫>利用BeautifulSoup爬取百度百科虚拟人物资料存入Mysql数据库
网页情况: 代码: import requests from requests.exceptions import RequestException from bs4 import Beautiful ...
- vue 路由跳转记住滚动位置,返回时回到上次滚动位置
参考:https://blog.csdn.net/qq_40204835/article/details/79853685 方法一: 利用Keep-Alive和监听器 1.首先在路由中引入需要的模块 ...
- 如何给Apache Pig自定义UDF函数?
近日由于工作所需,需要使用到Pig来分析线上的搜索日志数据,散仙本打算使用hive来分析的,但由于种种原因,没有用成,而Pig(pig0.12-cdh)散仙一直没有接触过,所以只能临阵磨枪了,花了两天 ...
- MessageBox用法
一 函数原型及参数 function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer; hWnd:对话框父窗口句柄, ...
- MyEclipse 最常用实用快捷键
- CentOS使用rpm离线安装mariadb
本文不再更新,可能存在内容过时的情况,实时更新请移步原文地址:CentOS使用rpm离线安装mariadb: 环境: CentOS Linux release 7.6.1810 (Core) mari ...