有时候我们的网络很垃圾,我的的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. 201521123004 《Java程序设计》第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 答:从ArrayList ...

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

    本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 1.2 可选:使用常规方法总结其他上课内容. 对象克隆:Clon ...

  3. 201521123022 《Java程序设计》 第一周学习总结

    1. 本章学习总结 通过这一周的学习,初次接触了Java,了解了Java与之前所用的C语言的不同之处,对JRE,JDK,JVM有了相应的基础了解.在安装了eclipse和JDK之后熟悉了一下eclip ...

  4. 201521123034《Java程序设计》第十二周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  5. 201521123045 <java程序设计>第11周学习总结

    201521123045 <java程序设计>第11周学习总结 1. 本周学习总结 2. 书面作业 2. 书面作业 Q1.1.互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问 ...

  6. 201521123024 java 第十周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 finally 题目4-2 1.1 截图你的提交结果(出现学 ...

  7. 工厂模式 and 单例模式

    工厂模式:使用工厂类使创建类与使用类分离,从而提高代码的易维护性,可扩展性等 工厂模式分位简单工厂模式和工厂方法模式 使用简单工厂模式的步骤:     1.创建父类及其子类         父类中有[ ...

  8. DAOFactory复用代码

    工厂设计模式 public class DaoFactory { private static final DaoFactory factory = new DaoFactory(); private ...

  9. Linux下安全证书申请以及配置到Nginx

    wget https://raw.githubusercontent.com/xdtianyu/scripts/master/lets-encrypt/letsencrypt.shchmod +x l ...

  10. mongoDB rs和sh关键字的作用

    rs是一个全局变量,其其中定义了很多分片操作的辅助函数, 可以sh.help()查看使用的辅助函数 这些是rs和sh所有函数 在mongoDB中有两种方法表示 例 sh.enableSharding( ...