Unity3D缓存图片

xiaoxiao2021-02-28  29

在某种情况下,在网络上下载图片的时候,由于网络等原加载图片会很慢,就需要将图片缓存到本地。这样在读取本地图片会很快。在网上也搜索了一些方法主要原理就是查找本地是否有这个文件,然后决定是去网上下载,还是本地加载。这里主要用到的方法就是读写本地文件和网上下载文件。下面是代码。

using UnityEngine; using System.Collections; using System.IO; using System; using UnityEngine.Events; using System.Security.Cryptography;//引用Md5转换功能 using System.Text; public class CacheImage { private static CacheImage instences = null; private string path = //Application.persistentDataPath; #if UNITY_EDITOR || UNITY_STANDALONE_WIN Application.dataPath + "/StreamingAssets/Cache"; #elif UNITY_IPHONE || UNITY_ANDROID Application.persistentDataPath; //persistentDataPath文件夹可读可写。 #else string.Empty; #endif private string name = "{0}.png"; private static UnityAction<Texture2D> cacheEvent; private static MonoBehaviour mono; public static CacheImage Cache(MonoBehaviour mb, UnityAction<Texture2D> callback) //标准类的单例 { cacheEvent = callback; mono = mb; if (instences == null) { instences = new CacheImage(); } return instences; } public void DownLoad(string url, string identifyId) { if (mono != null) { mono.StartCoroutine(LoadTexture(url, identifyId)); } } /// <summary> /// 判断是否本地有缓存 /// </summary> /// <param name="url"></param> /// <returns></returns> private IEnumerator LoadTexture(string url, string identifyId) { if (!string.IsNullOrEmpty(url)) { if (!File.Exists(Path.Combine(path, string.Format(name, identifyId)))) { yield return LoadNetWorkTexture(url, identifyId); } else { yield return LoadLocalTexture(url, identifyId); } } } /// <summary> /// 本地已缓存 /// </summary> /// <param name="url"></param> /// <returns></returns> private IEnumerator LoadLocalTexture(string url, string identifyId) { //已在本地缓存 Debug.Log("已在本地缓存"); string filePath = "file:///" + Path.Combine(path, string.Format(name, identifyId)); WWW www = new WWW(filePath); yield return www; cacheEvent.Invoke(www.texture); } /// <summary> /// 本地未缓存 /// </summary> /// <param name="url"></param> /// <returns></returns> private IEnumerator LoadNetWorkTexture(string url, string identifyId) { WWW www = new WWW((new Uri(url)).AbsoluteUri); yield return www; Debug.Log("本地未缓存"); if (!string.IsNullOrEmpty(www.error)) { Debug.Log("缓存失败"); Debug.Log(string.Format("Failed to load image: {0}, {1}", url, www.error)); yield break; } #if UNITY_EDITOR || UNITY_STANDALONE_WIN if (!Directory.Exists(path)) { Directory.CreateDirectory(path);//创建新路径 } #endif Texture2D image = www.texture; //将图片保存至缓存路径 byte[] pngData = image.EncodeToPNG(); File.WriteAllBytes(Path.Combine(path, string.Format(name, identifyId)), pngData); cacheEvent.Invoke(www.texture); } //计算字符串的Md5值 public static string GetMD5WithString(string input) { MD5 md5Hash = MD5.Create(); // 将输入字符串转换为字节数组并计算哈希数据 byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); // 创建一个 Stringbuilder 来收集字节并创建字符串 StringBuilder str = new StringBuilder(); // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串 for (int i = 0; i < data.Length; i++) { str.Append(data[i].ToString("x2"));//加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位 } // 返回十六进制字符串 return str.ToString(); } }

    上面的代码,没有继承MonoBehaviour不用拖到任何物体上就能使用,并使用单例。只要拖到项目的任意目录就能直接使用。下面是使用方法。

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class LoadImage : MonoBehaviour { public RawImage image; void Start() { string url = "http://www.shijunzh.com/wp-content/uploads/2017/06/cropped-icon.png"; string name = CacheImage.GetMD5WithString(url); CacheImage.Cache(this, CacheEvent).DownLoad(url, name); } void CacheEvent(Texture2D t) { image.texture = t; } }    其中,在Cache方法里要传的参数第一个是当前的脚本对象,里面要用到这个脚本去开启协程去网络和本地加载图片,第二个参数是一个委托方法,用来接收加载的图片的。在DownLoad方法里第一个参数是图片的url地址,第二个参数是保存到本地的图片名称,也是用这个名称去判断本地有没有这个图片的,所以这个参数使用MD5值保证他的唯一性。
转载请注明原文地址: https://www.6miu.com/read-1450152.html

最新回复(0)