Unity+NGUI打造网络图片异步加载与本地缓存工具类(二)

接上文,我们的工具类中的主要方法:

public  void SetAsyncImage(string url,UITexture texture)

按照前文分析的图片加载步骤来

public  void SetAsyncImage(string url,UITexture texture){

		//开始下载图片前,将UITexture的主图片设置为占位图
		texture.mainTexture = placeholder;

		//判断是否是第一次加载这张图片

		if (!File.Exists (path + url.GetHashCode())) {
						//如果之前不存在缓存文件

					StartCoroutine (DownloadImage (url, texture));

				}
		else {

					StartCoroutine(LoadLocalImage(url,texture));

				}

	}

这里判断缓存文件是否存在使用的是url.GetHashCode()方法,因为我们的图片文件名采用的是原URL的哈希码直接作为文件名来保存,重名概率可以忽略不计,也缩短了文件名的长度提高效率,这个做法借鉴于 iOS开源框架EGOImageView。

如果是第一次加载图片,这个URL对应的文件不存在,那么我们就去原URL下载图片然后赋值给控件

如果缓存文件夹中已有该文件,直接读取加载

由于前文的铺垫,我们的工具类已经是MonoBehaviour的单例子类,所以可以使用unity的异步函数StartCorutine()

接下来完成方法DownloadImage(string url,UITexture texture)

IEnumerator  DownloadImage(string url,UITexture texture){
		Debug.Log("downloading new image:"+path+url.GetHashCode());
		WWW www = new WWW (url);
		yield return www;

		Texture2D image = www.texture;
		//将图片保存至缓存路径
		byte[] pngData = image.EncodeToPNG();
		File.WriteAllBytes(path+url.GetHashCode(), pngData);  

		texture.mainTexture = image;

	}

这个方法很简单,然后是从缓存文件夹读取已经存在的图片方法LoadLocalImage(string url,UITexture texture)

注意这里不能使用Resources.Load()方法,因为我们的图片并没有存放在工程目录中,我仔细查阅了相关资料发现比较合适的方法应该还是使用unity的WWW类去加载文件url,即在文件路径的前方加上file:///使之成为一个文件url,然后使用www类读取,但是这个过程是本地的还是比较快

IEnumerator  LoadLocalImage(string url,UITexture texture){
		string filePath = "file:///" + path + url.GetHashCode ();

		Debug.Log("getting local image:"+filePath);
		WWW www = new WWW (filePath);
		yield return www;

		//直接贴图
		texture.mainTexture = www.texture;

	}

我们的工具类写好了

随便找个Panel添加一个带UITexture组件的节点,然后调用我们的工具方法,测试下运行结果:

第一次运行:

打开这个文件所在的文件夹(我这里使用的是windows系统,不同系统路径不一样)

这个图片已经加载在我们的图片控件上并且已经保存至了本地路径,也就是说我们再次运行之后,不会再进入if的第一种情况了,我们关掉程序再次运行:

正如我们所想,实际上这次是没有产生网络请求的,说明我的缓存已经有用,而且图片一下就出来了,不像上一次要等一会

接下来我们删掉缓存文件再次执行,又会调用第一个方法~

这个工具类先做到这里了,接下来图片切换效果已经加载过程的等待HUD等后面再研究。完整代码:

using UnityEngine;
using System.Collections;
using System.IO;

public class AsyncImageDownload :MonoBehaviour {

	public  Texture placeholder;
	public static AsyncImageDownload  Instance=null;

	private   string path=Application.persistentDataPath+"/ImageCache/" ;

	//构建单例
	public static AsyncImageDownload CreateSingleton()
	{
		if (!Directory.Exists(Application.persistentDataPath+"/ImageCache/")) {
			Directory.CreateDirectory(Application.persistentDataPath+"/ImageCache/");
		}

		GameObject obj = new GameObject ();
		obj.AddComponent<AsyncImageDownload> ();

		AsyncImageDownload loader= obj.GetComponent<AsyncImageDownload>();
		Instance=loader;
		loader.placeholder=Resources.Load("placeholder") as Texture;
		return loader;

	}

	public  void SetAsyncImage(string url,UITexture texture){

		//开始下载图片前,将UITexture的主图片设置为占位图
		texture.mainTexture = placeholder;

		//判断是否是第一次加载这张图片

		if (!File.Exists (path + url.GetHashCode())) {
						//如果之前不存在缓存文件

					StartCoroutine (DownloadImage (url, texture));

				}
		else {

					StartCoroutine(LoadLocalImage(url,texture));

				}

	}

	IEnumerator  DownloadImage(string url,UITexture texture){
		Debug.Log("downloading new image:"+path+url.GetHashCode());
		WWW www = new WWW (url);
		yield return www;

		Texture2D image = www.texture;
		//将图片保存至缓存路径
		byte[] pngData = image.EncodeToPNG();
		File.WriteAllBytes(path+url.GetHashCode(), pngData);  

		texture.mainTexture = image;

	}

	IEnumerator  LoadLocalImage(string url,UITexture texture){
		string filePath = "file:///" + path + url.GetHashCode ();

		Debug.Log("getting local image:"+filePath);
		WWW www = new WWW (filePath);
		yield return www;

		//直接贴图
		texture.mainTexture = www.texture;

	}
}
时间: 2024-12-27 16:01:47

Unity+NGUI打造网络图片异步加载与本地缓存工具类(二)的相关文章

Unity+NGUI打造网络图片异步加载与本地缓存工具类(一)

我们在移动端的开发中,异步网络图片加载用的非常的多,在unity当中虽然有AssetBundle的存在,一般是先加载好游戏资源然后再进入场景,但是还有不少地方能够用到异步网络图片的加载以及其缓存机制. 我之前也写过两个版本的ios中的异步网络图片加载helper类,所以今天按照同样的思路,也想做一个好用的helper类给大家使用以及简单的说下实现原理. 首先我们加载一张网络图片,要做的事情分步来讲为: 0.开始之前设置一张固定的图片作为占位图(placeholder),表示我们的图片还没加载好,

[原创]cocos2dx加载网络图片&amp;异步加载图片

[动机] 之前看到一款卡牌游戏,当你要看全屏高清卡牌的时候,游戏会单独从网络上下载,本地只存了非高清的,这样可以省点包大小,所以我萌生了实现一个读取网络图片的类. [联想] 之前浏览网页的时候经常看到一张图片渐进(由模糊变清晰)的显示,如果在游戏中,诸如像显示高清卡牌的时候,使用有这种方式去显示一张图片,这样的体验应该会稍微好些 [相关知识] png interlaced:png图片在导出的时候是可以选择 interlaced (Adam7)的,这样的存储的png在网页上显示会渐进显示, 这种i

Android实战简易教程-第四十九枪(两种方式实现网络图片异步加载)

加载图片属于比较耗时的工作,我们需要异步进行加载,异步加载有两种方式:1.通过AsyncTask类进行:2.通过Handler来实现,下面我们就来看一下如何通过这两种方式实现网络图片的异步加载. 一.AsyncTask方式 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co

android异步加载图片并缓存到本地实现方法

图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如大图片使用LRU缓存策略或懒加载缓存策略.今天首先介绍一下本地缓存图片 在android项目中访问网络图片是非常普遍性的事情,如果我们每次请求都要访问网络来获取图片,会非常耗费流量,而且图片占用内存空间也比较大,图片过多且不释放的话很容易造成内存溢出.针对上面遇到的两个问题,首先耗费流量我们可以将图片第一次加载上面缓存到本地,以后如果本地有就直接从本地加载.图片过多造成内存溢出,这个是最不容易解决的,要想一些好的缓存策略,比如

基于 unity ngui 上的滚动加载__UiVirtual

在游戏里面经常会有背包,好友,对话,这样的列表.当列表的内容多了,如果一打开界面就对所有内容进行实例化,会消耗大量的性能,且会造成UI上的卡顿. 于是便需要,在列表里面只实例化屏幕上可见的item.屏幕外的不需要进行实例化. 这里 https://github.com/textcube/infinitescroll 便是我们要找的内容 如图: 然而在在看源码的时候我们不难发现,这个开源的git仓库,是对移动到屏幕外面的item进行了destroy(见WordItem.cs),对移动到屏幕上的it

iOS之加载等待指示器(工具类)

#import "CXDView.h" @interface CXDView () //动态图 @property (strong, nonatomic) UIImageView *loadingImageView; //提示文字 @property (strong, nonatomic) UILabel *toastLabel; @end @implementation CXDView #pragma mark - 初始化 - (instancetype)init { self =

windows phone 8.0 的网络图片异步加载方案

买了一本林政的8.1UI的书,看到一个使用弱引用对像来解决图片缓存的问题,刚好自已写的应用也遇到这个问题,于是小改动了一下代码,搬到了8.0版本来使用,代码由 zhxilin℃+ 大神提供了部分解决代码. 下面提供一个下载链接,提供给有需要的朋友下载. http://files.cnblogs.com/files/dreamIT/%E5%9B%BE%E7%89%87%E5%BC%82%E6%AD%A5%E5%8A%A0%E8%BD%BD.rar

浅谈Android中的异步加载之ListView中图片的缓存及优化三

     隔了很久没写博客,现在必须快速脉动回来.今天我还是接着上一个多线程中的异步加载系列中的最后一个使用异步加载实现ListView中的图片缓存及其优化.具体来说这次是一个综合Demo.但是个人觉得里面还算有点价值的就是里面的图片的缓存的实现.因为老实说它确实能在实际的项目中得到很好的应用.主要学习来源于慕课网中的异步加载学习,来自徐宜生大神的灵感.本次也就是对大神所讲知识的一个总结及一些个人的感受吧. 这次是一个综合的Demo,主要里面涉及到的知识主要有:网络编程.异步加载.JSON解析.

SDWebImage图片二级缓存异步加载基本原理

关于SDWebImage SDWebImage是一个针对图片加载的插件库,提供了一个支持缓存的用于异步加载图片的下载工具,特别的为常用的UI元素:UIImageView,UIButton和MKAnnotationView提供了Category类别扩展,可以作为一个很方便的工具.其中SDWebImagePrefetcher可以预先下载图片,方便后续使用. SDWebImage的Github地址为:https://github.com/rs/SDWebImage SDWebImage的几点特性 为U