看似简单的功能,实施起来却是有着一堆大坑。

按着基本功能来写吧

1.选择图片并显示到Image控件中

2.图片序列化为byte数组以及反序列化

3.本地存储与读取

1.选择图片:

逻辑就是使用FileOpenPicker选择一个图片文件后,将该文件从StorageFile对象转化成可以赋值给Image.Source的ImageSource类的对象。

(这里需要注意的是WriteableBitmap,BitmapImage,SoftwareBitmapSource都可以赋值给Image.Source,你赋值给Image.Source的是什么对象,你就只能用as符把Image.Source转化成什么对象。 比如:你使用WriteableBitmap赋值给Image.Source,那么你后面只能用 var t = imageSource as WriteableBitmap,  你如果使用var t = imageSource as BitmapImage的话编译器不会报错,但是t的值最后会是null)

1.1 选取图片文件并实例化为WriteableBitmap对象

  1. private async void ChoosePhoto()
  2. {
  3. FileOpenPicker fileOpenPicker = new FileOpenPicker();
  4. fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
  5. fileOpenPicker.FileTypeFilter.Add(".jpg");
  6. fileOpenPicker.FileTypeFilter.Add(".png");
  7. fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
  8. StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync();
  9. if (imgFile_tmp == null)
  10. {
  11. return;
  12. }
  13. else
  14. {
  15. this.imgFile = imgFile_tmp;
  16. using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read))
  17. {
  18. var srcImage = new WriteableBitmap(,);
  19. await srcImage.SetSourceAsync(stream);
  20. Image_Thumbnail.Source = srcImage;
  21. }
  22. }
  23. }

1.2 选取图片文件并实例化为BitmapImage对象

  1. private async void ChoosePhoto()
  2. {
  3. FileOpenPicker fileOpenPicker = new FileOpenPicker();
  4. fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
  5. fileOpenPicker.FileTypeFilter.Add(".jpg");
  6. fileOpenPicker.FileTypeFilter.Add(".png");
  7. fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
  8. StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync();
  9. if (imgFile_tmp == null)
  10. {
  11. return;
  12. }
  13. else
  14. {
  15. this.imgFile = imgFile_tmp;
  16. using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read))
  17. {
  18. var srcImage = new BitmapImage();
  19. await srcImage.SetSourceAsync(stream);
  20. Image_Thumbnail.Source = srcImage;
  21. }
  22. }
  23. }

1.3 选取图片实例化为SoftwareBitmapSource对象

  1. private async void ChoosePhoto()
  2. {
  3. FileOpenPicker fileOpenPicker = new FileOpenPicker();
  4. fileOpenPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
  5. fileOpenPicker.FileTypeFilter.Add(".jpg");
  6. fileOpenPicker.FileTypeFilter.Add(".png");
  7. fileOpenPicker.ViewMode = PickerViewMode.Thumbnail;
  8. StorageFile imgFile_tmp = await fileOpenPicker.PickSingleFileAsync();
  9. if (imgFile_tmp == null)
  10. {
  11. return;
  12. }
  13. else
  14. {
  15. SoftwareBitmap softwareBitmap;
  16. this.imgFile = imgFile_tmp;
  17. using (IRandomAccessStream stream = await imgFile.OpenAsync(FileAccessMode.Read))
  18. {
  19. // Create the decoder from the stream
  20. BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
  21. // Get the SoftwareBitmap representation of the file
  22. softwareBitmap = await decoder.GetSoftwareBitmapAsync();
  23. }
  24. if (softwareBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8 || softwareBitmap.BitmapAlphaMode == BitmapAlphaMode.Straight)
  25. {
  26. softwareBitmap = SoftwareBitmap.Convert(softwareBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
  27. }
  28. var source = new SoftwareBitmapSource();
  29. await source.SetBitmapAsync(softwareBitmap);
  30. // Set the source of the Image control
  31. Image_Thumbnail.Source = source;
  32. }
  33. }

2.图片序列化为byte数组以及反序列化

2.1 WriteableBitmap对象(Image.Source赋值的时候使用的是WriteableBitmap)序列化为byte数组

  1. public static async Task<byte[]> SaveToBytesAsync(ImageSource imageSource)
  2. {
  3. byte[] imageBuffer;
  4. var localFolder = ApplicationData.Current.TemporaryFolder;
  5. var file = await localFolder.CreateFileAsync("temp.jpg", CreationCollisionOption.GenerateUniqueName);
  6. using (var ras = await file.OpenAsync(FileAccessMode.ReadWrite, StorageOpenOptions.None))
  7. {
  8. WriteableBitmap bitmap = imageSource as WriteableBitmap;
  9. var stream = bitmap.PixelBuffer.AsStream();
  10. byte[] buffer = new byte[stream.Length];
  11. await stream.ReadAsync(buffer, , buffer.Length);
  12. BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, ras);
  13. encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, buffer);
  14. await encoder.FlushAsync();
  15.  
  16. var imageStream = ras.AsStream();
  17. imageStream.Seek(, SeekOrigin.Begin);
  18. imageBuffer = new byte[imageStream.Length];
  19. var re = await imageStream.ReadAsync(imageBuffer, , imageBuffer.Length);
  20. }
  21. await file.DeleteAsync(StorageDeleteOption.Default);
  22. return imageBuffer;
  23. }

2.2Byte数组反序列化为ImageSource(WriteableBitmap)

  1. public static async Task<ImageSource> SaveToImageSource(byte[] imageBuffer)
  2. {
  3. ImageSource imageSource = null;
  4. try
  5. {
  6. using (MemoryStream stream = new MemoryStream(imageBuffer))
  7. {
  8. var ras = stream.AsRandomAccessStream();
  9. BitmapDecoder decoder = await BitmapDecoder.CreateAsync(BitmapDecoder.JpegDecoderId, ras);
  10. var provider = await decoder.GetPixelDataAsync();
  11. byte[] buffer = provider.DetachPixelData();
  12. WriteableBitmap bitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
  13. await bitmap.PixelBuffer.AsStream().WriteAsync(buffer, , buffer.Length);
  14. imageSource = bitmap;
  15. }
  16. }
  17. catch (Exception ex)
  18. {
  19.  
  20. }
  21. return imageSource;
  22. }

2.3 BitmapImage对象序列化为byte数组

需要注意的是这里所调用的BitmspImage对象,必须是使用BitmapImage(uri)方法实例化出来的BitmapImage对象,因此下列方法主要用于实现对网络图片的序列化与反序列化。

如果使用从FileOpenPicker选取出来图片文件实例化出来的BitmapImage对象的话,该对象的UriSource属性为空,故下列方法无法实现。

  1. RandomAccessStreamReference random = RandomAccessStreamReference.CreateFromUri(himage.UriSource);
  2. IRandomAccessStreamWithContentType streamWithContent = await random.OpenReadAsync();
  3. byte[] buffer = new byte[streamWithContent.Size];
  4. await streamWithContent.ReadAsync(buffer.AsBuffer(), (uint)streamWithContent.Size, InputStreamOptions.None);

2.4 byte数组反序列化为BitmapImage对象

  1. BitmapImage image = new BitmapImage();
  2. using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
  3. {
  4. await stream.WriteAsync(obj.ImgArray.AsBuffer());
  5. stream.Seek();
  6. await image.SetSourceAsync(stream);
  7. }

3.本地存储与读取

(需要注意的是:StorageFile这类的存储操作貌似只允许存一些简单的数据类型,所以我的解决方法就是把自定义的类的对象里的图片转化为byte数组,然后再将自定义类的对象的List转化成json字符串存进文件,读取文件的时候再读出这些Json字符串并反序列化为我需要的类型)

3.1 存储数据

  1. public static async Task SaveData(string filename, T data)
  2. {
  3. try
  4. {
  5. StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
  6. using (IRandomAccessStream raStream = await file.OpenAsync(FileAccessMode.ReadWrite))
  7. {
  8. using (IOutputStream outStream = raStream.GetOutputStreamAt())
  9. {
  10.  
  11. var json = JsonConvert.SerializeObject(data);
  12. DataContractSerializer serializer = new DataContractSerializer(typeof(string));
  13. serializer.WriteObject(outStream.AsStreamForWrite(), json);
  14. var t =JsonConvert.DeserializeObject<T>(json);
  15. await outStream.FlushAsync();
  16. }
  17. }
  18. }
  19. catch (Exception exc)
  20. {
  21. throw exc;
  22. }
  23. }

3.2 加载数据

  1. public static async System.Threading.Tasks.Task<List<ShowInfo>> LoadData(string filename)
  2. {
  3. try
  4. {
  5. if (ApplicationData.Current.LocalFolder.TryGetItemAsync(filename) != null)
  6. {
  7. StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(filename);
  8. using (IInputStream inStream = await file.OpenSequentialReadAsync())
  9. {
  10. DataContractSerializer serializer = new DataContractSerializer(typeof(string));
  11. var json = (string)serializer.ReadObject(inStream.AsStreamForRead());
  12. var data = JsonConvert.DeserializeObject<List<ShowInfo>>(json);
  13. return data;
  14. }
  15. }
  16. else
  17. {
  18. return new List<ShowInfo>();
  19. }
  20.  
  21. }
  22. catch (FileNotFoundException ex)
  23. {
  24. throw ex;
  25. }
  26. catch (Exception ex)
  27. {
  28. throw ex;
  29. }
  30. }

UWP关于图片缓存的那些破事儿的更多相关文章

  1. 关于CAE的那点儿破事儿

    CAE是计算机辅助工程的英文简写,所涵盖的范围甚是广泛.现在很多人提到CAE,总是联想到结构有限元计算,更有甚者认为有限元就是CAE.还有人把所有的工程数值计算都称作有限元.本文就这一话题,来谈谈关于 ...

  2. 优化 UWP 中图片的内存占用

    跟图片打交道的 UWP 应用或多或少都会遇到图片带来的性能问题,就算不主要处理图片,做个论坛做个新闻客户端都涉及到大量图片.一个帖子.一篇文章里多半都是些高清大图,这些图片一张即可占用程序 1~2M ...

  3. Android图片缓存之Lru算法

    前言: 上篇我们总结了Bitmap的处理,同时对比了各种处理的效率以及对内存占用大小.我们得知一个应用如果使用大量图片就会导致OOM(out of memory),那该如何处理才能近可能的降低oom发 ...

  4. android使用ImageLoader实现图片缓存(安卓开发必备)

    相信大家在学习以及实际开发中基本都会与网络数据打交道,而这其中一个非常影响用户体验的就是图片的缓存了,若是没有弄好图片缓存,用户体验会大大下降,总会出现卡顿情况,而这个问题尤其容易出现在ListVie ...

  5. Android图片缓存之Glide进阶

    前言: 前面学习了Glide的简单使用(Android图片缓存之初识Glide),今天来学习一下Glide稍微复杂一点的使用. 图片缓存相关博客地址: Android图片缓存之Bitmap详解 And ...

  6. Android图片缓存之初识Glide

    前言: 前面总结学习了图片的使用以及Lru算法,今天来学习一下比较优秀的图片缓存开源框架.技术本身就要不断的更迭,从最初的自己使用SoftReference实现自己的图片缓存,到后来做电商项目自己的实 ...

  7. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

  8. AFNetworking图片缓存问题

    AFNetworking网络库已经提供了很好的图片缓存机制,效率是比较高的,但是我发现没有直接提供清除缓存的功能,可项目通常都需要添加 清除功能的功能,因此,在这里我以UIImageView+AFNe ...

  9. IOS编程 图片缓存模块设计

    手机客户端为什么会留存下来?而不是被一味的Wap替代掉?因为手机客户端有Wap无可替代的优势,就是自身较强的计算能力. 手机中不可避免的一环:图片缓存,在软件的整个运行过程中显得尤为重要. 先简单说一 ...

随机推荐

  1. icons 在线网站

    icons https://www.iconfinder.com/ http://v3.bootcss.com/components/ http://fontawesome.io/icons/ htt ...

  2. 阿里巴巴 Weex

    原文链接:https://blog.csdn.net/zz901214/article/details/79168707/ 分享嘉宾:侑夕 阿里巴巴高级前端工程师(上张帅哥的图镇楼,看完,更有动力学习 ...

  3. DNS 原理

    一.DNS 是什么? DNS (Domain Name System 的缩写)的作用非常简单,就是根据域名查出IP地址.你可以把它想象成一本巨大的电话本. 举例来说,如果你要访问域名math.stac ...

  4. css fixed 失效问题解法

    https://stackoverflow.com/questions/11258877/fixed-element-disappears-in-chrome 开启css硬件加速,transform: ...

  5. BIF

    list()把一个可迭代对象转化为列表 tuple()把一个可迭代对象转化为元祖 str()把参数对象转化为字符串 len()返回参数的长度 max()返回序列或者参数集合中的最大值 min()返回序 ...

  6. How to change system keyboard keymap layout on CentOS 7 Linux

    The easiest way to swap between keymaps and thus temporarily set keys to different language by use o ...

  7. select2插件用法

    1.修改默认查询方法,使其可以根据value查询 this.element.select2({ allowClear: true, matcher: function (term, text, ele ...

  8. MySQL解压包的安装教程

    一.下载MySQL解压包 解压过的文件夹里面是没有 data 文件夹的. 二.创建文件 1.在根目录下创建 my.ini文件 内容如下: [mysqld] # 设置mysql的安装目录 basedir ...

  9. 在html中使用javascript总结

    对于初学者运行代码的第一步,首先是怎么把你所写的js代码与html代码之间关联起来,只有关联了,js才能控制html中的代码,进而达到控制页面的目的,我总结了html引用js的方法,一方面可以时时复习 ...

  10. 【机器学习】异常检测算法(I)

    在给定的数据集,我们假设数据是正常的 ,现在需要知道新给的数据Xtest中不属于该组数据的几率p(X). 异常检测主要用来识别欺骗,例如通过之前的数据来识别新一次的数据是否存在异常,比如根据一个用户以 ...