Unity图片加载器
来源:互联网 发布:计算机三级数据库 编辑:程序博客网 时间:2024/06/10 04:33
在http://www.tuicool.com/articles/ZFrMZnM的基础上对AsyncImageDownload进行了完善,完整代码如下:
using UnityEngine;
using System.Collections;using System.IO;using System.Collections.Generic;using System;/// <summary>/// 图片(Texture)加载类/// 三级缓存:1、如果在内存中,则先从内存获取;2、没有则查看本地是否存在,存在则从本地获取;3、没有则再从网络进行获取并保存到本地。/// </summary>public class AsyncImageDownload : MonoBehaviour{ /// <summary> /// 默认图片 /// </summary> public Texture placeholder; /// <summary> /// 单例 /// </summary> public static AsyncImageDownload Instance = null; /// <summary> /// 本地图片保存路径。如果是android环境,Application.persistentDataPath值为/storage/emulated/legacy/Android/data/com.xxx.xxx/files/ /// </summary> private string imageCacheRootPath = Application.persistentDataPath + "/ImageCache/"; /// <summary> /// 缓存在内存里的texture,重复利用。key是url对应图片保存成本地文件的绝对路径。 /// texture采用弱引用方式,当系统需要回收时这里不会因为强引用阻止回收。 /// </summary> private Dictionary<string, WeakReference> textureCache = new Dictionary<string,WeakReference>(); /// <summary> /// 应用开始运行时,可以调用此方法进行初始化 /// </summary> /// <returns>AsyncImageDownload单例对象</returns> 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("default_cover") as Texture;// 默认图片 Debug.Log("image save path : " + Instance.imageCacheRootPath); return loader; } /// <summary> /// 根据url加载对应图片。 /// </summary> /// <param name="url">图片url</param> /// <param name="texture">UITexture</param> /// <param name="action">加载完成时的回调</param> /// <param name="needCache">是否需要缓存到内存中(如果非长时间显示在页面,不建议缓存)</param> public void SetAsyncImage(string url, UITexture texture, Action action = null, bool needCache = true) { if (string.IsNullOrEmpty(url)) { Debug.LogWarning("[SetAsyncImage] url is null."); return; } // 只有需要缓存时才从内存中查找 if (needCache) { // 从内存获取 if (getFromCache(imageCacheRootPath + url.GetHashCode(), texture)) { if (action != null) { action(); } return; } } //判断是否是第一次加载这张图片(以url的hashcode作为文件名) if (!File.Exists(imageCacheRootPath + url.GetHashCode())) { //如果之前不存在缓存文件 texture.StopCoroutine("DownloadImage");//UITexture.StopCoroutine可以停止之前的已经无用的协程 texture.StartCoroutine(DownloadImage(url, texture, action, needCache)); } // 从本地加载 else { texture.StopCoroutine("LoadLocalImage"); texture.StartCoroutine(LoadLocalImage(imageCacheRootPath + url.GetHashCode(), texture, action, needCache)); } } /// <summary> /// 加载本地图片。缓存到内存里。 /// </summary> /// <param name="path">本地文件绝对路径</param> /// <param name="texture">UITexture</param> /// <param name="action">加载完成时的回调</param> public void SetLocalImage(string path, UITexture texture, Action action = null) { if (string.IsNullOrEmpty(path)) { Debug.LogWarning("[SetLocalImage] path is null."); return; } // 从内存获取 if (getFromCache(path, texture)) { if (action != null) { action(); } return; } // 先判断该文件是否存在,不存在直接返回(这样会显示默认图片);如果不做这个判断进入LoadLocalImage,界面上会显示成红色问号。 FileInfo fi = new FileInfo(path); if (!fi.Exists) { Debug.LogError("Path is Not Exists! " + path); return; } texture.StopCoroutine("LoadLocalImage"); texture.StartCoroutine(LoadLocalImage(path, texture, action)); } /// <summary> /// 清空指定key的缓存 /// </summary> /// <param name="filePath"></param> public void clearCache(string filePath) { if (textureCache.ContainsKey(filePath)) { textureCache.Remove(filePath); } } /// <summary> /// /// </summary> /// <param name="url">图片url</param> /// <param name="texture">UITexture</param> /// <param name="action">加载完成时的回调</param> /// <param name="needCache">是否需要缓存到内存中</param> /// <returns></returns> IEnumerator DownloadImage(string url, UITexture texture, Action action = null, bool needCache = true) { int filename = url.GetHashCode(); Debug.Log("[DownloadImage]downloading new image : " + filename); yield return new WaitForSeconds(0.008f);//如果界面频繁快速切换,之前的图片根本不需要加载,所以这里稍微延迟一会儿再请求网络。 WWW www = new WWW(url); yield return www; if (www.error != null) { Debug.LogWarning("[DownloadImage] www.error : " + www.error); if (action != null) { action(); } } else { Debug.Log("[DownloadImage]download ok : " + filename); Texture2D image = www.texture; // The data must be an image in JPG or PNG format. If the data is not a valid image, the generated texture will be a small image of a question mark.(红色问号,大小为8*8) if (image == null || (image.width == 8 && image.height == 8))//如果image为空,或者为红色问号(无效图片)。 { Debug.LogError("[DownloadImage]www.texture is null or a question mark, return."); if (action != null) { action(); } } else { image.wrapMode = TextureWrapMode.Clamp;//将Texture的循环模式设为拉伸,Texture边界设为拉伸就不会出现白线。默认是平铺,如果是平铺的话,可能会出现两张图片交界处显示白线的问题。 texture.mainTexture = image; if (needCache) { textureCache[imageCacheRootPath + url.GetHashCode()] = new WeakReference(image); } if (action != null) { action(); } //将图片保存至缓存路径 byte[] pngData = www.bytes; Debug.Log("[DownloadImage] " + filename + " , size : " + (pngData.Length / 1024) + "KB"); File.WriteAllBytes(imageCacheRootPath + filename, pngData); } } } IEnumerator LoadLocalImage(string filePath, UITexture texture, Action action = null, bool needCache = true) { Debug.Log("getting local image :" + filePath); yield return new WaitForSeconds(0.008f); WWW www = new WWW("file:///" + filePath); yield return www; if (www.error != null) { Debug.LogWarning("[LoadLocalImage] www.error : " + www.error); DeleteFile(filePath); } else { Texture2D image = www.texture; //The data must be an image in JPG or PNG format. If the data is not a valid image, the generated texture will be a small image of a question mark.(红色问号,大小为8*8) if (image == null || (image.width == 8 && image.height == 8))//如果image为空,或者为红色问号(无效图片)。 { Debug.LogError("www.texture is null or a question mark, delete it."); DeleteFile(filePath); } else { image.wrapMode = TextureWrapMode.Clamp;//将Texture的循环模式设为拉伸,Texture边界设为拉伸就不会出现白线。默认是平铺,如果是平铺的话,可能会出现两张图片交界处显示白线的问题。 //直接贴图 texture.mainTexture = image; if (needCache) { textureCache[filePath] = new WeakReference(image); } } } if (action != null) { action(); } } /// <summary> /// 从textureCache读取 /// </summary> /// <param name="localPath"></param> /// <param name="texture"></param> /// <returns></returns> private bool getFromCache(string localPath, UITexture texture) { if (textureCache.ContainsKey(localPath)) { WeakReference wr = textureCache[localPath]; if (wr != null && wr.IsAlive) { texture.mainTexture = (Texture2D)wr.Target; if (texture.mainTexture == null)// 有可能在获取到的瞬间被回收了 { return false; } return true; } } return false; } private void DeleteFile(string filePath) { FileInfo fi = new FileInfo(filePath); if (fi.Exists) { Debug.LogWarning("[DeleteFile] delete this file : " + filePath); fi.Delete(); } } }
0 0
- Unity图片加载器
- Unity 加载网络图片
- Unity 加载网络图片
- unity 加载图片文件
- Unity 异步加载图片
- unity 加载图片出现问号
- unity加载图片、音频、视频
- Unity 加载本地图片文件
- Unity加载图片到UI
- Unity Windows选择图片并加载
- unity 文件、图片加载与保存
- unity 文件、图片加载与保存
- 【Unity】用Unity加载电脑C盘中的一张图片
- unity加载文件的方法-用加载图片举例
- Unity--动态加载网络图片和本地图片文件
- Unity--动态加载网络图片和本地图片文件
- unity打包web版后自定义加载图片
- [unity3d]unity打包web版后自定义加载图片
- opencv-相机标定步骤、评估标定误差以及标定之后图像坐标到世界坐标的转换
- System.img的查看/处理
- Cocoa pod使用Tips
- 根视图隐藏导航栏,子视图返回时没有出现导航栏
- Android系统启动时间(不是系统当前时间)的获取
- Unity图片加载器
- JdbcTemplate 简介
- 单个Tomcat配置多个域并配置多个证书
- 使用keras对mnist数据集做分类
- ScrollView嵌套ListView,listItem.measure(0,0);报空指针异常NullPointerException
- Blobs, Layers, and Nets: anatomy of a Caffe model
- Android 跳转硬件公众号
- 在windows、linux中开启nginx的Gzip压缩大大提高页面、图片加载速度
- 30s倒计时