有时候我们的网络很垃圾,我的的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


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

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

  1. win10 uwp 读取保存WriteableBitmap 、BitmapImage

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

  2. 2019-9-2-win10-uwp-存放网络图片到本地

    title author date CreateTime categories win10 uwp 存放网络图片到本地 lindexi 2019-09-02 12:57:38 +0800 2018-2 ...

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

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

  4. 【Win10 UWP】QQ SDK(二):SDK的回调处理

    上一讲,我们介绍了QQ SDK的使用方法,请看<[Win10 UWP]QQ SDK(一):SDK基本使用方法> 一. 回调的基本形式 从前面的介绍中我们知道,我们的应用和QQ客户端之间需要 ...

  5. Win10 UWP应用发布流程

    简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...

  6. win10 UWP 应用设置

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

  7. win10 UWP 序列化

    将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象. .NET Framewor ...

  8. 【广告】win10 uwp 水印图床 含代码

    本文主要是广告我的软件. 图床可以加速大家写博客上传图片的时间,通过简化我们的操作来得到加速. 在写博客的时候,我们发现,我们需要上传一张图片,需要先打开图片,然后选择本地图片,然后上传. 但是我经常 ...

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

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

随机推荐

  1. 201521123119《Java程序设计》第7周学习总结

    1. 本周学习总结 2. 书面作业 Q1.ArrayList代码分析 Q1.1 解释ArrayList的contains源代码 这段代码的主要目的是判断在对ArrayList遍历时所用的方法,在输入参 ...

  2. 201521123017 《Java程序设计》第6周学习总结

    1. 本周学习总结 <> 2. 书面作业 Q1.clone方法 1.1 Object对象中的clone方法是被protected修饰,在自定义的类中覆盖clone方法时需要注意什么? 1. ...

  3. 201521123035《Java程序设计》第二周学习总结

    1.本周学习总结 这周学习了各种类与对象,还有基本类型的打包器,最主要的是字符串对象,老师还特地花了一节课时间讲解代码与习题. 2.书面作业 1.使用Eclipse关联jdk源代码,并查看String ...

  4. Python[小甲鱼007了不起的分支和循环]

    加载背景音乐播放背景音乐(设置单曲循环)我方飞机诞生interval = 0while True:if 用户是否点击关闭按钮退出程序breakinterval += 1if interval = 50 ...

  5. java第九次学习总结

    1. 本周学习总结 2.. 书面作业 1.常用异常 题目5-1 1.1 提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避免? 以前编写的代码经常出现异 ...

  6. 通过Excel认识POI

    1.POI是什么 Apache POI - the Java API for Microsoft Documents,顾名思义,Apache的三方包,用来操作微软office文档的,多数时候用来操作e ...

  7. Spring MVC的文件上传

    1.文件上传 文件上传是项目开发中常用的功能.为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data.只有在这种情况下,浏览器才会把用户 ...

  8. Java学习笔记四---打包成双击可运行的jar文件

    写笔记四前的脑回路是这样的: 前面的学习笔记二,提到3个环境变量,其中java_home好理解,就是jdk安装路径:classpath指向类文件的搜索路径:path指向可执行程序的搜索路径.这里的类文 ...

  9. 改用Struts2.5 出现404 错误

    这个是因为现在Struts 使用  2.5   只需要8 个 jar 包 Xworks-core 已经加到 struts-core中了 原因 是  Jar 包 冲突  导致 的    其次 如果 使用 ...

  10. 参加Java培训你必须知道的五点真相!

    相信大家都有过到招聘网站投简历.找工作的经历.当一份份简历发出三天后,左等右等连一个电话没有等来,心中不免有些失落,有些焦虑.这个时侯,很多培训机构就会纷纷给你打电话以各种名义让你参加各种IT技能培训 ...