博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
淘宝UWP--自定义图片缓存
阅读量:6293 次
发布时间:2019-06-22

本文共 5326 字,大约阅读时间需要 17 分钟。

一、应用场景

在淘宝应用首页,会有很多张图片,而这些首页图片不会经常改变,所以就需要缓存下来。这样就不必每次都从网络获取。

二、比较对象

1.系统缓存

对于系统缓存,我们不需要做什么处理。只需要把网络图片的URL赋值给Image控件就行了。这样系统就会在每次需要用到图片的时候,有限查找缓存里有没有之前下载好的。

2.自建缓存区域

自建缓存不给Image控件赋URL,而是把图片DownLoad下来,生成一个bitmap,然后把bitmap赋值给Image。同时将这个bitmap存储下来。当下次要用到这幅图的时候,就直接从存储的位置找到这幅图。

三、自建缓存方法

下边这段代码将uri[]数组中的图片下载下来,然后通过WriteToFile()函数将图片保存到本地,同时,记下存储的文件名。

SoftwareBitmap sb = await DownloadImage(uri[i]);if (sb != null){  //sb = await ReadFromFile(fileName[i]);  SoftwareBitmapSource source = new SoftwareBitmapSource();  await source.SetBitmapAsync(sb);  this.insideImage.Source = source;  sb = await DownloadImage(uri[i]);  fileName[i] = await WriteToFile(sb);}

当你需要使用图片的时候,使用下列代码,通过ReadFromFile()函数将图片读取出来就行了。

for (int i = 0; i < 50; i++){
  //SoftwareBitmap sb = await DownloadImage(uri[i]);  SoftwareBitmap sb = await ReadFromFile(fileName[i]);  SoftwareBitmapSource source = new SoftwareBitmapSource();   await source.SetBitmapAsync(sb);  this.insideImage.Source = source;   //source.Dispose();}

 

四、效率对比

下边我通过对比两种缓存机制发现各有用武之地。

1.对于几百K到几兆的大图片,系统缓存有速度优势。

2.对于几K到几十K的小图片,自建缓存区有速度优势。

测试背景1:三张大图片,循环33次(共99次)

图片大小:338k 618k 1810k

 

PC测试

         

系统缓存(CPU周期)

3066584

3058505

3079367

3078989

3076976

自建缓存(CPU周期)

53669280

51842991

52839051

52078772

52305373

 

Phone测试

       

系统缓存(CPU周期)

31852799

32008575

32200748

31970601

31839003

自建缓存(CPU周期)

741909215

750950455

765863510

760865505

781048686

 

结论一:对于几百K到几兆的大图片,系统缓存有速度优势。

 

测试背景2:三张小图片,循环33次(共99次)

图片大小:3k 6k 60k

PC测试

系统缓存(CPU周期)

3057284

3057637

3080880

3063350

3059105

自建缓存(CPU周期)

1316247

1318369

1364584

1333684

1362956

 

Phone测试

系统缓存(CPU周期)

32085084

31751734

31744715

31852230

32064768

自建缓存(CPU周期)

27114317

26041012

26821794

27365796

30211258

 

结论二:对于几K到几十K的小图片,自建缓存区有速度优势。

 手机淘宝项目测试数据:

测试背景:50张小图片,循环一次(共50次)

系统缓存

CPU周期

23689650

21589548

25409150

25186302

23121251

 

RAM

51

52

50

52

52

             
             

自建缓存

CPU周期

3186761

2892837

2963193

2942235

2741501

 

RAM

61

63

61

60

59

 PS:RAM占用是峰值,稳定后两种方式RAM占用相同。

五、测试方法

通过给一个Image控件赋值,来看到效果。

1、系统缓存

系统缓存测试不能通过直接改变url的方式,因为系统缓存是异步的,他不会等一个图片加载好再加载另一个图,而是直接忽略了之前的改变。

private async void test1(){  stopwatch.Reset();  stopwatch.Start();  BitmapImage bi = new BitmapImage();  bi.UriSource = new Uri(uri[0]);  this.insideImage.Source = bi; } private void insideImage_ImageOpened(object sender, RoutedEventArgs e){  times++;  if (times == 50)  {    stopwatch.Stop();    textBox.Text = "任务"+testnum.ToString()+"用时:" + stopwatch.ElapsedTicks + ".";    return;  }  BitmapImage bi = new BitmapImage();  bi.UriSource = new Uri(uri[times]);  this.insideImage.Source = bi; }

 2、自建缓存

private async void test2(){  stopwatch.Reset();  stopwatch.Start();  for (int i = 0; i < 50; i++)  {    //SoftwareBitmap sb = await DownloadImage(uri[i]);    SoftwareBitmap sb = await ReadFromFile(fileName[i]);    SoftwareBitmapSource source = new SoftwareBitmapSource();    await source.SetBitmapAsync(sb);    if (i % 3 == 0)    {      this.insideImage.Source = source;    }     else if (i % 3 == 1)    {      this.insideImage1.Source = source;    }     else if (i % 3 == 2)    {      this.insideImage2.Source = source;    }    //source.Dispose();   }  stopwatch.Stop();  textBox.Text = "任务" + testnum.ToString() + "用时:" + stopwatch.ElapsedTicks + ".";}

 

附:关键代码代码

ReadFromFile()函数通过文件名读取图片 ,特别注意这句话

SoftwareBitmapsoftwareBitmap = awaitdecoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);

 一定要加上编码方式,不然会报错。

public async Task
ReadFromFile(string filename){  StorageFile file = await _localFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);  //var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri( filename));  using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read))  {    // Create the decoder from the stream    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);    // Get the SoftwareBitmap representation of the file    SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);    return softwareBitmap;  }}

 WriteToFile()函数将bitmap写入存储区

public async Task
WriteToFile(SoftwareBitmap softwareBitmap){  string fileName = Path.GetRandomFileName();  if (softwareBitmap != null)  {    // save image file to cache    StorageFile file = await _localFolder.CreateFileAsync(fileName, CreationCollisionOption.OpenIfExists);    using (IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.ReadWrite))    {      BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);      encoder.SetSoftwareBitmap(softwareBitmap);      await encoder.FlushAsync();  }}  return fileName; }

DownloadImage()函数通过url下载图片,返回bitmap

private async Task
DownloadImage(string url){  try  {    HttpClient hc = new HttpClient();    HttpResponseMessage resp = await hc.GetAsync(new Uri(url));    resp.EnsureSuccessStatusCode();    IInputStream inputStream = await resp.Content.ReadAsInputStreamAsync();    IRandomAccessStream memStream = new InMemoryRandomAccessStream();    await RandomAccessStream.CopyAsync(inputStream, memStream);    BitmapDecoder decoder = await BitmapDecoder.CreateAsync(memStream);    SoftwareBitmap softBmp = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);    return softBmp;  }  catch (Exception ex)  {    return null;  }}

 

转载地址:http://zqdta.baihongyu.com/

你可能感兴趣的文章
Android 6.0指纹识别App开发案例
查看>>
正文提取算法
查看>>
轻松学PHP
查看>>
Linux中的网络监控命令
查看>>
this的用法
查看>>
windows下安装redis
查看>>
CentOS7 yum 安装git
查看>>
启动日志中频繁出现以下信息
查看>>
httpd – 对Apache的DFOREGROUND感到困惑
查看>>
分布式锁的一点理解
查看>>
idea的maven项目,install下载重复下载本地库中已有的jar包,而且下载后jar包都是lastupdated问题...
查看>>
2019测试指南-web应用程序安全测试(二)指纹Web服务器
查看>>
树莓派3链接wifi
查看>>
js面向对象编程
查看>>
Ruby中类 模块 单例方法 总结
查看>>
jQuery的validate插件
查看>>
5-4 8 管道符 作业控制 shell变量 环境变量配置
查看>>
Enumberable
查看>>
开发者论坛一周精粹(第五十四期) 求购备案服务号1枚!
查看>>
validate表单验证及自定义方法
查看>>