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}");
- }
- }
- }
- }
- }
|