| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 | using System;using System.Collections.Generic;using System.IO;using System.Linq;using ET;using UnityEngine;using UnityEngine.Networking;namespace GFGGame{    public class PictureDataManager : SingletonBase<PictureDataManager>    {        //本地地址        private const string _loadUrl = "gfgpicture";        //正在操作的文件队列        private Queue<string> _queueOperateFileList = new Queue<string>();        /// <summary>        /// 所有照片的二进制        /// </summary>        private Dictionary<string, Texture2D> _allPicByteDic = new Dictionary<string, Texture2D>();        public async ETTask<Texture2D> GetPicNTexture(string tempUrl)        {            string fileNameKey = GetUrlFileName(tempUrl);            if (_allPicByteDic.TryGetValue(fileNameKey, out Texture2D texture2D))            {                // 可能存在                if (texture2D != null &&                    texture2D.width > 0 &&                    texture2D.height > 0 &&                    texture2D.GetPixels().Length > 0)                {                    // 检查纹理的格式是否支持                    if (texture2D.format == TextureFormat.RGBA32 ||                        texture2D.format == TextureFormat.RGB24)                    {                        // 纹理有效,可以正常显示                        return texture2D; // 或者转换为 NTexture 对象                    }                    else                    {                        Debug.LogError("Texture format is not supported.");                        // 处理不支持的纹理格式                        return await DownloadOrLoadPic(tempUrl);                    }                }                else                {                    Debug.LogWarning("Texture is invalid or has no pixels.");                    // 处理无效的纹理                    return await DownloadOrLoadPic(tempUrl);                }            }            //TODO 一定不存在, 需要去进行下载            return await DownloadOrLoadPic(tempUrl);        }        //从远端进行下载        public async ETTask<Texture2D> DownloadOrLoadPic(string tempUrl)        {            string fileName = GetUrlFileName(tempUrl);            Texture2D texture2D = await DownloadPictureAsync(tempUrl);            if (texture2D == null)            {                return GetDefaultTexture();            }            //不为null, 以协程的方式存储到内存以及, 本地            _allPicByteDic[fileName] = texture2D;            //加入队列            _queueOperateFileList.Enqueue(fileName);            SavaPicToLoad().Coroutine();            return texture2D;        }        //存储图片文件到本地,如果存在就进行删除本地或者覆盖,以当前的为最新的进行记录        public async ETTask SavaPicToLoad()        {            var tempList = _queueOperateFileList.ToList();            for (int i = 0; i < tempList.Count; i++)            {                if (_queueOperateFileList.Count == 0)                {                    break;                }                string fileName = _queueOperateFileList.Dequeue();                if (string.IsNullOrEmpty(fileName))                {                    continue;                }                if (!_allPicByteDic.TryGetValue(fileName, out Texture2D texture2D))                {                    continue;                }                if (texture2D == null)                {                    continue;                }                // 获取本地存储路径                string localPath = Path.Combine(Application.persistentDataPath, fileName);                // 存储图片文件到本地                try                {                    // 将 Texture2D 转换为字节数组                    byte[] imageData = texture2D.EncodeToPNG();                    // 如果文件已经存在,则覆盖                    if (File.Exists(localPath))                    {                        File.Delete(localPath);                    }                    // 将字节数组写入文件                    File.WriteAllBytes(localPath, imageData);                }                catch (Exception ex)                {                    Debug.LogError($"Failed to save image to local path: {ex.Message}");                }            }            await ETTask.CompletedTask;        }        private async ETTask<Texture2D> DownloadPictureAsync(string tempUrl, int count = 0)        {            string fileName = GetUrlFileName(tempUrl);                        if (count >= 3)            {                PromptController.Instance.ShowFloatTextPrompt("下载失败");                ViewManager.Hide<ModalStatusView>();                return null;            }            using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(tempUrl))            {                var asyncOperation = request.SendWebRequest();                while (!asyncOperation.isDone)                {                    await TimerComponent.Instance.WaitTillAsync(100); // 等待一段时间后继续检查                }                if (request.result == UnityWebRequest.Result.ProtocolError ||                    request.result == UnityWebRequest.Result.ConnectionError)                {                    count += 1;                    return await DownloadPictureAsync(tempUrl, count); // 递归重试                }                else                {                    Texture2D texture = (request.downloadHandler as DownloadHandlerTexture).texture;                    return texture;                }            }        }        // 获取存储文件的完整路径        public static string GetFilePath(string fileName)        {            // 获取持久化数据路径            string persistentDataPath = Application.persistentDataPath;            // 创建“zhaoPian”文件夹路径            string folderPath = Path.Combine(persistentDataPath, _loadUrl);            // 确保文件夹存在            if (!Directory.Exists(folderPath))            {                Directory.CreateDirectory(folderPath);            }            // 返回文件的完整路径            return Path.Combine(folderPath, fileName);        }        /// <summary>        /// 获取下载地址的文件名, 包含后缀 TODO 需要增加容错        /// </summary>        /// <param name="url"></param>        /// <returns></returns>        public static string GetUrlFileName(string url)        {            // 创建一个 Uri 对象            Uri uri = new Uri(url);            // 获取 URL 的路径部分            string path = uri.AbsolutePath;            // 从路径中提取文件名            string fileName = System.IO.Path.GetFileName(path);            // // 获取不包含扩展名的文件名            // string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(fileName);            return fileName;        }        //TODO 默认纹理, 让客户端来修改这个代码, 定义一个默认的 Texture2D        private Texture2D GetDefaultTexture()        {            // 创建一个简单的默认图片,比如纯色或空白图片            Texture2D defaultTexture = new Texture2D(2, 2);            Color[] pixels = defaultTexture.GetPixels();            for (int i = 0; i < pixels.Length; i++)            {                pixels[i] = Color.gray; // 设置为灰色的默认图片            }            defaultTexture.SetPixels(pixels);            defaultTexture.Apply();            return defaultTexture;        }        //初始化的时候根据图片保存时间, 加载最多50条到内存中        public void LoadAllImages()        {            // 获取文件夹路径            string folderPath = Path.Combine(Application.persistentDataPath, _loadUrl);            // 检查文件夹是否存在            if (Directory.Exists(folderPath))            {                // 获取所有图片文件路径(假设图片格式为.jpg和.png)                string[] imageFiles = Directory.GetFiles(folderPath, "*.*", SearchOption.TopDirectoryOnly);                // 过滤出图片文件,并按修改时间排序                var imageFileInfos = imageFiles                    .Where(filePath => filePath.EndsWith(".jpg") || filePath.EndsWith(".png"))                    .Select(filePath => new FileInfo(filePath))                    .OrderByDescending(fileInfo => fileInfo.LastWriteTime)                    .ToList();                int loadedCount = 0;                const int maxImagesToLoad = 50;                foreach (var fileInfo in imageFileInfos)                {                    string filePath = fileInfo.FullName;                    try                    {                        // 读取图片数据                        byte[] imageData = File.ReadAllBytes(filePath);                        // 创建纹理并加载数据                        Texture2D texture = new Texture2D(2, 2); // 创建一个2x2的空纹理                        if (texture.LoadImage(imageData))                        {                            // 提取文件名作为字典的键                            string fileName = Path.GetFileName(filePath);                            // 将纹理添加到字典                            _allPicByteDic[fileName] = texture;                            Debug.Log($"Loaded {fileName}");                            loadedCount++;                            // 如果已经加载了最大数量的图片,停止加载并删除剩余较旧的图片                            if (loadedCount >= maxImagesToLoad)                            {                                DeleteOldImages(imageFileInfos, loadedCount);                                return;                            }                        }                        else                        {                            Debug.LogWarning($"Failed to load image from {filePath}");                        }                    }                    catch                    {                        Debug.LogWarning($"Error processing file: {filePath}");                    }                }            }            else            {                Debug.LogWarning($"Folder not found: {folderPath}");            }        }        // 删除较旧的图片        private void DeleteOldImages(List<FileInfo> imageFileInfos, int loadedCount)        {            // 从已经加载的图片后面开始删除            for (int i = loadedCount; i < imageFileInfos.Count; i++)            {                string filePath = imageFileInfos[i].FullName;                try                {                    File.Delete(filePath);                    Debug.Log($"Deleted {filePath}");                }                catch (Exception ex)                {                    Debug.LogWarning($"Failed to delete {filePath}: {ex.Message}");                }            }        }    }}
 |