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();

ImageCache

2019-9-2-win10-uwp-存放网络图片到本地的更多相关文章

  1. win10 uwp 存放网络图片到本地

    有时候我们的网络很垃圾,我的的UWP要在第一次打开网络图片,就把图片存放到本地,下次可以从本地打开. 有时候用户使用的是流量网络,不能每次都联网下载. 我们不得在应用存放用户打开的图片. 这就是先把图 ...

  2. win10 uwp 读取保存WriteableBitmap 、BitmapImage

    我们在UWP,经常使用的图片,数据结构就是 BitmapImage 和 WriteableBitmap.关于 BitmapImage 和 WriteableBitmap 区别,我就不在这里说.主要说的 ...

  3. win10 UWP 应用设置

    win10 UWP 应用设置 简单的把设置需要的,放到微软自带的LocalSettings LocalSettings.Values可以存放几乎所有数据 如果需要存放复合数据,一个设置项是由多个值组成 ...

  4. win10 uwp 如何开始写 uwp 程序

    本文告诉大家如何创建一个 UWP 程序. 这是一系列的 uwp 入门博客,所以写的很简单 本文来告诉大家如何创建一个简单的程序 安装 VisualStudio 在开始写 UWP 需要安装 Visual ...

  5. win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序

    本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...

  6. win10 uwp win2d CanvasVirtualControl 与 CanvasAnimatedControl

    本文来告诉大家 CanvasVirtualControl ,在什么时候使用这个控件. 在之前的入门教程win10 uwp win2d 入门 看这一篇就够了我直接用的是CanvasControl,实际上 ...

  7. win10 uwp 发布旁加载自动更新

    在很多企业使用的程序都是不能通过微软商店发布,原因很多,其中我之前的团队开发了很久的应用,结果发现没有用户能从微软应用商店下载所以我对应用商店没有好感.但是作为一个微软粉丝,怎么能不支持 UWP 开发 ...

  8. win10 uwp 通过 Win2d 完全控制笔迹绘制逻辑

    本文来告诉大家如何通过 Win2d 完全控制笔迹绘制逻辑,本文适合用来实现复杂的自定义逻辑,可以完全控制笔迹的行为.包括在书写过程中切换模式,如进行手势擦除切换为橡皮擦模式 本文提供的方法适合用来做复 ...

  9. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

随机推荐

  1. LUOGU P3382 【模板】三分法 (三分)

    传送门 解题思路 三分,填坑.每次取l与r的中间值mid,然后向左移一点点,向右移一点点进行判断,判断时用秦九韶算法即可. #include<iostream> #include<c ...

  2. JavaSE_12_序列化流和打印流

    1.1 序列化流概述 Java 提供了一种对象序列化的机制.用一个字节序列可以表示一个对象,该字节序列包含该对象的数据.对象的类型和对象中存储的属性等信息.字节序列写出到文件之后,相当于文件中持久保存 ...

  3. iframe跨域数据传递

    项目中需要和其他单位合作开发,方案采用iframe嵌入页面,开发过程中设计到了跨域数据的传递,初步方案决定使用html5 API postMessage进行iframe跨域数据传递: 域名A下的页面 ...

  4. JavaScript中数组的基础知识和相关方法

      数组基础 数组是大多数语言里面最常见的一种数据结构,它是一个有序的值列表. 创建数组 1.创建字面量数组 let arr=[]; 2.创建构造函数数组 let arr=new Array(); 注 ...

  5. TmodJs:常用语法

    ylbtech-TmodJs:常用语法 1.返回顶部 1.循环 {{each items as item index}} <tr> <td>{{index+1}}</td ...

  6. Netty 框架基本流程

    服务端 package com.mypractice.netty.server; import java.net.InetSocketAddress; import io.netty.bootstra ...

  7. js如何往数组Array中添加元素 (2013-09-04 10

    unshift:将参数添加到原数组开头,并返回数组的长度 pop:删除原数组最后一项,并返回删除元素的值:如果数组为空则返回undefined push:将参数添加到原数组末尾,并返回数组的长度 co ...

  8. elasticsearch filters特性

    使用filters优化查询 ElasticSearch支持多种不同类型的查询方式,这一点大家应该都已熟知.但是在选择哪个文档应该匹配成功,哪个文档应该呈现给用户这一需求上,查询并不是唯一的选择.Ela ...

  9. Centos7解决在同一局域网内无法使用ssh连接

    参考: https://www.cnblogs.com/liyuanhong/articles/5785368.html 一.修改网卡设置 nano /etc/sysconfig/network-sc ...

  10. php 网页内容抓取

    最近抓的2个网站内容的代码 列表页抓取:第一种使用phpquery插件,可以快速获取,第二种它是api,所以直接获取 load_third("phpQuery.php"); /** ...