插眼 : 2024/03/15 更新
1. 更新获取到目录文件夹下包括 JPG 和 PNG 格式的所有图片
2. 调整了 函数 顺序
3. 增加了 函数调用示例
TextureKit.LoadSpritesToArr(Application.streamingAssetsPath + "/Seed/SeedIcons");
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Networking;
public static class TextureKit
{
/// <summary>
/// 返回 Texture2D 本地图片转Texture2D
/// </summary>
/// <param name="sFullPath">图片完整路径</param>
/// <returns></returns>
public static Texture2D LoadTexture2DSingle(string sFullPath)
{
if (!File.Exists(sFullPath)) return null;
Image image = Image.FromStream(new MemoryStream(FileToBytes(sFullPath)));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(sFullPath));
return t2d;
}
/// <summary>
/// 返回List 在指定目录下加载的所有图片的 Texture2D
/// </summary>
/// <returns></returns>
public static List<Texture2D> LoadTexture2DToList(string sFold)
{
List<Texture2D> lLoadT2ds = new List<Texture2D>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetImagesPath(sFold);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
if (filePaths.Count > 0)
{
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//放到集合里面
lLoadT2ds.Add(t2d);
Debug.Log(filePaths[i]);
}
}
return lLoadT2ds;
}
/// <summary>
/// 返回单张 Sprite 本地图片转Sprite
/// </summary>
/// <param name="sFullPath">图片完整路径</param>
/// <returns></returns>
public static Sprite LoadSpriteSingle(string sFullPath)
{
if (!File.Exists(sFullPath))
{
Debug.LogError("LoadSpriteSingle方法 路径不正确");
return null;
}
Image image = Image.FromStream(new MemoryStream(FileToBytes(sFullPath)));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(sFullPath));
//创建Sprite
Sprite sprite = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), new Vector2(0.5f, 0.5f));
return sprite;
}
/// <summary>
/// 返回List 在指定目录下加载的所有图片的 Sprite 包括jpg 和 png
/// 使用示例: TextureKit.LoadSpritesToArr(Application.streamingAssetsPath + "/Seed/SeedIcons");
/// </summary>
/// <returns></returns>
public static Sprite[] LoadSpritesToArr(string sFold)
{
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetMultiNameSuffixFilePath(sFold);
Sprite[] SpritesArr = new Sprite[filePaths.Count];
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//创建Sprite
Sprite sprite = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), new Vector2(0.5f, 0.5f));
SpritesArr[i] = sprite;
}
return SpritesArr;
}
/// <summary>
/// 返回List 在指定目录下加载的所有图片的 Sprite 包括 jpg 和 png格式
/// 使用示例: TextureKit.LoadSpritesToList(Application.streamingAssetsPath + "/Seed/SeedIcons");
/// </summary>
/// <returns></returns>
public static List<Sprite> LoadSpritesToList(string sFold)
{
List<Sprite> lLoadSprites = new List<Sprite>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetMultiNameSuffixFilePath(sFold);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//创建Sprite
Sprite sprite = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), new Vector2(0.5f, 0.5f));
//放到集合里面
lLoadSprites.Add(sprite);
}
return lLoadSprites;
}
/// <summary>
/// 返回List 在指定目录下加载的所有图片的 Sprite
/// </summary>
/// <returns></returns>
public static List<Sprite> LoadAndSetPivotSpritesToList(string sFold, Vector2 pivot)
{
List<Sprite> lLoadSprites = new List<Sprite>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetImagesPath(sFold);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//创建Sprite
Sprite sprite = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), pivot);
//放到集合里面
lLoadSprites.Add(sprite);
}
return lLoadSprites;
}
/// <summary>
/// 得到指定后缀格式的所有文件路径
/// 默认后缀为 "*.PNG"
/// </summary>
/// <returns></returns>
public static List<string> GetImagesPath(string sFold, string sNameSuffix = "*.PNG")
{
List<string> filePaths = new List<string>();
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", sNameSuffix);
try
{
string[] dirs = Directory.GetFiles(sFold, sNameSuffix);
if (dirs.Length > 0)
{
for (int j = 0; j < dirs.Length; j++)
{
if (!File.Exists(dirs[j]))
{
Debug.LogError(dirs[j] + "GetImagesPath方法 路径不正确");
return null;
}
filePaths.Add(dirs[j]);
Debug.Log("图片路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "张图片");
}
else
{
Debug.Log("文件夹内未读取到文件" + sFold);
}
}
catch (Exception e)
{
Debug.Log(e);
}
return filePaths;
}
/// <summary>
/// 得到多个指定后缀格式的所有文件路径
/// Case : 需自己修改 imgtype按照格式去添加后缀格式
/// </summary>
/// <returns></returns>
public static List<string> GetMultiNameSuffixFilePath(string sFold)
{
List<string> filePaths = new List<string>();
string imgtype = "*.JPG|*.PNG";
string[] ImageType = imgtype.Split('|');
for (int i = 0; i < ImageType.Length; i++)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
string[] dirs = Directory.GetFiles(sFold, ImageType[i]);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
Debug.Log("文件路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "个文件");
}
return filePaths;
}
/// <summary>
/// 文件 转 字节
/// </summary>
/// <param name="sFilePath"></param>
/// <returns></returns>
public static byte[] FileToBytes(string sFilePath)
{
//读取到文件
FileStream files = new FileStream(sFilePath, FileMode.Open);
//新建比特流对象
byte[] bArrFileBytes = new byte[files.Length];
//将文件写入对应比特流对象
files.Read(bArrFileBytes, 0, bArrFileBytes.Length);
//关闭文件
files.Close();
//返回比特流的值
return bArrFileBytes;
}
/// <summary>
/// 文件夹目录最多只保留指定数量的图片
/// sNameSuffix 后缀名
/// </summary>
public static void DeleteWhenOverLoad(string sFoldPath, string sNameSuffix = "*.PNG", int iFoldMaxSaveNum = 40)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", "*.PNG");
//string[] dirs = Directory.GetFiles(sFoldPath, "*.PNG");
string[] dirs = Directory.GetFiles(sFoldPath, sNameSuffix);
//需要删除的数量
int iNeedDeleteNum = dirs.Length - iFoldMaxSaveNum;
if (iNeedDeleteNum > 0)
{
for (int i = 0; i < iNeedDeleteNum; i++)
{
File.Delete(dirs[i]);
}
}
}
/// <summary>
/// IO保存 Texture2D 到本地为 Png
/// </summary>
/// <param name="texture">传入要保存的 Texture2D</param>
/// <param name="sFullPath">传入你要保存的位置 完整路径</param>
public static void SaveTexture2DToPNG(Texture2D texture, string sFullPath)
{
第一种方式
//var bytes = texture.EncodeToPNG();
//var file = File.Open(sFullPath, FileMode.Create);
//var binary = new BinaryWriter(file);
//binary.Write(bytes);
//file.Close();
// 第二种方式 EncodeToPNG这个会导致主线程卡顿 携程一样
System.IO.File.WriteAllBytes(sFullPath, texture.EncodeToPNG());
}
/// <summary>
/// 默认使用 携程来保存图片到路径 其他方式可能造成主线程一瞬间的卡顿 携程完成有回调
/// </summary>
/// <param name="sBlendFaceImageName"></param>
/// <param name="texture"></param>
/// <param name="sFullPath"></param>
/// <returns></returns>
public static IEnumerator SaveTexture2DToPNGCoroutine(string sBlendFaceImageName, Texture2D texture, string sFullPath, Action callback)
{
//yield return new WaitForSeconds(5f);
yield return new WaitForEndOfFrame();
byte[] bytes = texture.EncodeToPNG();
//将纹理数据,转化成一个png图片
System.IO.File.WriteAllBytes(sFullPath, bytes);
//写入文件之后触发
callback?.Invoke();
#region
使用示例
携程保存图片
//StartCoroutine(TextureKit.Instance.SaveTexture2DToPNGCoroutine(sBlendFaceImageName, m_tBlendTexture as Texture2D, DataManager.Instance.sBlendFaceImagesFoldPath + sBlendFaceImageName, (() =>
//{
// //Debug.Log("妈妈再也不担心我存图片了");
// // 人脸融合完成,广播事件
// QEventSystem.SendEvent(FaceEvent.OnFaceMergeFinish, sBlendFaceImageName);
//})));
#endregion
}
/// <summary>
/// PNG 图片存储大小压缩
/// </summary>
/// <param name="imagePath"></param>
public static void CompressPNG(string imagePath)
{
byte[] fileData = File.ReadAllBytes(imagePath);
Texture2D tex = new Texture2D((int)(Screen.width), (int)(Screen.height), TextureFormat.RGB24, true);
tex.LoadImage(fileData);
float miniSize = Mathf.Max(tex.width, tex.height);
float scale = 1200.0f / miniSize;
if (scale > 1.0f)
{
scale = 1.0f;
}
Texture2D temp = ScaleTexture(tex, (int)(tex.width * scale), (int)(tex.height * scale));
byte[] pngData = temp.EncodeToPNG();
// string miniImagePath = imagePath.Replace(".png", "_min.jpg");
File.WriteAllBytes(imagePath, pngData);
}
/// <summary>
/// 图片尺寸大小缩放
/// </summary>
/// <param name="source"></param>
/// <param name="targetWidth"></param>
/// <param name="targetHeight"></param>
/// <returns></returns>
public static Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
{
Texture2D result = new Texture2D(targetWidth, targetHeight, source.format, true);
UnityEngine.Color[] rpixels = result.GetPixels(0);
float incX = ((float)1 / source.width) * ((float)source.width / targetWidth);
float incY = ((float)1 / source.height) * ((float)source.height / targetHeight);
for (int px = 0; px < rpixels.Length; px++)
{
rpixels[px] = source.GetPixelBilinear(incX * ((float)px % targetWidth), incY * ((float)Mathf.Floor(px / targetWidth)));
}
result.SetPixels(rpixels, 0);
result.Apply();
return result;
}
/// <summary>
/// 两张图像合并
/// </summary>
/// <param name="src1"></param>
/// <param name="src2"></param>
/// <returns></returns>
public static Texture2D ImageConbine(Texture2D src1, Texture2D src2)
{
// 偏差
int offsetX = 0;
int offsetY = 0;
for (int x = 0; x < src2.width; x++)
{
for (int y = 0; y < src2.height; y++)
{
if (src2.GetPixel(x, y).a > 0.9)
{
src1.SetPixel(src1.width - x + offsetX, src1.height + y + offsetY, src2.GetPixel(x, y));
}
}
}
src1.Apply();
return src1;
}
/// <summary>
/// 输入一张texture2D,返回矩形区域内的不透明的像素
/// </summary>
/// <param name="src"></param>
/// <param name="dstWidth"></param>
/// <param name="dstHeight"></param>
/// <param name="offsetX"></param>
/// <param name="offsetY"></param>
/// <returns></returns>
public static Texture2D GetRectOpaqueT2D(Texture2D src, int dstWidth = 729, int dstHeight = 729, int offsetX = 612, int offsetY = 175)
{
Texture2D miniMask = new Texture2D(dstWidth, dstHeight, TextureFormat.RGBA32, false);
for (int x = 0; x < src.width; x++)
{
for (int y = 0; y < src.height; y++)
{
if (src.GetPixel(x, y).a > 0.9)
{
miniMask.SetPixel(x - offsetX, y - offsetY, src.GetPixel(x, y));
}
}
}
//miniMask.alphaIsTransparency = true;
miniMask.Apply();
return miniMask;
}
/// <summary>
/// RenderTexture 转 Texture2D
/// </summary>
/// <param name="renderT"></param>
/// <returns></returns>
public static Texture2D GetTexture2DFromRenderTexture(RenderTexture renderT)
{
if (renderT == null)
Debug.LogError("RenderTexture 未赋值");
int width = renderT.width;
int height = renderT.height;
Texture2D tex2d = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture.active = renderT;
tex2d.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex2d.Apply();
//byte[] b = tex2d.EncodeToPNG();
//Destroy(tex2d);
//File.WriteAllBytes(Application.dataPath + "1.jpg", b);
return tex2d;
}
/// <summary>
/// 保存 RenderTexture
/// </summary>
/// <param name="renderT"></param>
/// <returns></returns>
public static void SaveRenderTextureToPNG(string sFullPath, RenderTexture renderT, Action<Texture2D> callback)
{
try
{
Texture2D tex2d = GetTexture2DFromRenderTexture(renderT);
byte[] b = tex2d.EncodeToPNG();
File.WriteAllBytes(sFullPath, b);
//写入文件之后触发
callback?.Invoke(tex2d);
}
catch (Exception e)
{
Debug.Log(e.Message);
throw;
}
}
public static IEnumerator SaveRenderTextureToPNGAsyncGPU(string sFullPath, RenderTexture renderT, Action<Texture2D> callback)
{
int nw = renderT.width;
int nh = renderT.height;
GraphicsFormat format = renderT.graphicsFormat;
UnityEngine.Rendering.AsyncGPUReadbackRequest request = UnityEngine.Rendering.AsyncGPUReadback.Request(renderT, 0);
yield return 0;
while (!request.done)
{
yield return new WaitForEndOfFrame();
}
if (request.hasError)
{
Debug.Log("GPU readback error detected.");
yield break;
}
byte[] array = request.GetData<byte>().ToArray();
byte[] datas = ImageConversion.EncodeArrayToPNG(array, format, (uint)nw, (uint)nh);
try
{
File.WriteAllBytes(sFullPath, datas);
//写入文件之后触发
Texture2D tex2d = GetTexture2DFromRenderTexture(renderT);
callback?.Invoke(tex2d);
}
catch (Exception e)
{
Debug.Log(e.Message);
throw;
}
}
public static void OnSingletonInit()
{
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
public class NewTintTextureKit : MonoBehaviour
{
string sFold = Application.streamingAssetsPath + "/0";
public List<Sprite> sprite = new List<Sprite>();
void Start()
{
sprite = LoadSpritesToList(sFold);
}
/// <summary>
/// 返回List 在指定目录下加载的所有图片的 Sprite
/// </summary>
/// <returns></returns>
public List<Sprite> LoadSpritesToList(string sFold, string sNameSuffix = "*.PNG")
{
List<Sprite> lLoadSprites = new List<Sprite>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetImagesPath(sFold, sNameSuffix);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
StartCoroutine(DownloadImage(filePaths[i], (sprite) =>
{
//放到集合里面
lLoadSprites.Add(sprite);
}));
}
return lLoadSprites;
}
/// <summary>
/// 得到指定后缀格式的所有文件路径
/// 默认后缀为 "*.PNG"
/// </summary>
/// <returns></returns>
public List<string> GetImagesPath(string sFold, string sNameSuffix = "*.PNG")
{
List<string> filePaths = new List<string>();
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", sNameSuffix);
try
{
string[] dirs = Directory.GetFiles(sFold, sNameSuffix);
if (dirs.Length > 0)
{
for (int j = 0; j < dirs.Length; j++)
{
if (!File.Exists(dirs[j]))
{
Debug.LogError(dirs[j] + "GetImagesPath方法 路径不正确");
return null;
}
filePaths.Add(dirs[j]);
//Debug.Log("图片路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "张图片");
}
}
catch (Exception)
{
Debug.Log("文件夹内未读取到文件" + sFold);
}
return filePaths;
}
IEnumerator DownloadImage(string MediaUrl, Action<Sprite> action)
{
UnityWebRequest request = UnityWebRequestTexture.GetTexture(MediaUrl);
yield return request.SendWebRequest();
if (request.isNetworkError || request.isHttpError)
Debug.Log(request.error);
else
{
Texture2D tex = ((DownloadHandlerTexture)request.downloadHandler).texture;
Sprite sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(tex.width / 2, tex.height / 2));
action?.Invoke(sprite);
}
}
}
使用只需要将单例方法更改一下就行,后续将持续进行更新,用到哪补充到哪
如在使用过程中有任何不适,请评论区插眼,谢谢
插眼 : 2020/10/31 更新
1. 返回 在指定目录下加载的所有图片的 Texture2D
2. 文件 转 字节
3. 得到指定后缀格式的所有文件路径
4. 得到多个指定后缀格式的所有文件路径
5. 文件夹目录最多只保留指定数量的图片
6. IO保存 Texture2D 到本地为 Png
7. 默认使用 携程来保存图片到路径 其他方式可能造成主线程一瞬间的卡顿 携程完成有回调
8. PNG 图片存储大小压缩
9. 图片尺寸大小缩放
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using UnityEngine;
namespace QFramework.Example
{
public class TextureKit : ISingleton
{
private TextureKit() { }
public static TextureKit Instance
{
get { return SingletonProperty<TextureKit>.Instance; }
}
/// <summary>
/// 返回 在指定目录下加载的所有图片的 Texture2D
/// </summary>
/// <returns></returns>
public List<Texture2D> LoadTexture2DToList(string sFold)
{
List<Texture2D> lLoadT2ds = new List<Texture2D>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetImagesPath(sFold);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//放到集合里面
lLoadT2ds.Add(t2d);
}
return lLoadT2ds;
}
/// <summary>
/// 文件 转 字节
/// </summary>
/// <param name="sFilePath"></param>
/// <returns></returns>
public static byte[] FileToBytes(string sFilePath)
{
//读取到文件
FileStream files = new FileStream(sFilePath, FileMode.Open);
//新建比特流对象
byte[] bArrFileBytes = new byte[files.Length];
//将文件写入对应比特流对象
files.Read(bArrFileBytes, 0, bArrFileBytes.Length);
//关闭文件
files.Close();
//返回比特流的值
return bArrFileBytes;
}
/// <summary>
/// 得到指定后缀格式的所有文件路径
/// 默认后缀为 "*.PNG"
/// </summary>
/// <returns></returns>
public List<string> GetImagesPath(string sFold, string sNameSuffix = "*.PNG")
{
List<string> filePaths = new List<string>();
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", sNameSuffix);
string[] dirs = Directory.GetFiles(sFold, sNameSuffix);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
//Debug.Log("图片路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "张图片");
return filePaths;
}
/// <summary>
/// 得到多个指定后缀格式的所有文件路径
/// Case : 需自己修改 imgtype按照格式去添加后缀格式
/// </summary>
/// <returns></returns>
public List<string> GetMultiNameSuffixFilePath(string sFold)
{
List<string> filePaths = new List<string>();
string imgtype = "*.JPG|*.PNG";
string[] ImageType = imgtype.Split('|');
for (int i = 0; i < ImageType.Length; i++)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
string[] dirs = Directory.GetFiles(sFold, ImageType[i]);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
Debug.Log("文件路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "个文件");
}
return filePaths;
}
/// <summary>
/// 文件夹目录最多只保留指定数量的图片
/// sNameSuffix 后缀名
/// </summary>
public void DeleteWhenOverLoad(string sFoldPath, string sNameSuffix = "", int iFoldMaxSaveNum = 40)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", "*.PNG");
string[] dirs = Directory.GetFiles(sFoldPath, "*.PNG");
Log.I("文件夹目录大小 : " + dirs.Length);
//需要删除的数量
int iNeedDeleteNum = dirs.Length - iFoldMaxSaveNum;
if (iNeedDeleteNum > 0)
{
for (int i = 0; i < iNeedDeleteNum; i++)
{
File.Delete(dirs[i]);
Log.I("++++++++++++++ 文件被删除 +++++" + dirs[i]);
}
}
}
/// <summary>
/// IO保存 Texture2D 到本地为 Png
/// </summary>
/// <param name="texture">传入要保存的 Texture2D</param>
/// <param name="sFullPath">传入你要保存的位置 完整路径</param>
public void SaveTexture2DToPNG(Texture2D texture, string sFullPath)
{
第一种方式
//var bytes = texture.EncodeToPNG();
//var file = File.Open(sFullPath, FileMode.Create);
//var binary = new BinaryWriter(file);
//binary.Write(bytes);
//file.Close();
// 第二种方式 EncodeToPNG这个会导致主线程卡顿 携程一样
System.IO.File.WriteAllBytes(sFullPath, texture.EncodeToPNG());
}
/// <summary>
/// 默认使用 携程来保存图片到路径 其他方式可能造成主线程一瞬间的卡顿 携程完成有回调
/// </summary>
/// <param name="sBlendFaceImageName"></param>
/// <param name="texture"></param>
/// <param name="sFullPath"></param>
/// <returns></returns>
public IEnumerator SaveTexture2DToPNGCoroutine(string sBlendFaceImageName, Texture2D texture, string sFullPath, Action callback)
{
//yield return new WaitForSeconds(5f);
yield return new WaitForEndOfFrame();
byte[] bytes = texture.EncodeToPNG();
//将纹理数据,转化成一个png图片
System.IO.File.WriteAllBytes(sFullPath, bytes);
//写入文件之后触发
callback?.Invoke();
#region
// 使用示例
// 携程保存图片
//StartCoroutine(TextureKit.Instance.SaveTexture2DToPNGCoroutine(sBlendFaceImageName, m_tBlendTexture as Texture2D, DataManager.Instance.sBlendFaceImagesFoldPath + sBlendFaceImageName, (() =>
//{
// //Debug.Log("妈妈再也不担心我存图片了");
// // 人脸融合完成,广播事件
// QEventSystem.SendEvent(FaceEvent.OnFaceMergeFinish, sBlendFaceImageName);
//})));
#endregion
}
/// <summary>
/// PNG 图片存储大小压缩
/// </summary>
/// <param name="imagePath"></param>
public void CompressPNG(string imagePath)
{
byte[] fileData = File.ReadAllBytes(imagePath);
Texture2D tex = new Texture2D((int)(Screen.width), (int)(Screen.height), TextureFormat.RGB24, true);
tex.LoadImage(fileData);
float miniSize = Mathf.Max(tex.width, tex.height);
float scale = 1200.0f / miniSize;
if (scale > 1.0f)
{
scale = 1.0f;
}
Texture2D temp = ScaleTexture(tex, (int)(tex.width * scale), (int)(tex.height * scale));
byte[] pngData = temp.EncodeToPNG();
// string miniImagePath = imagePath.Replace(".png", "_min.jpg");
File.WriteAllBytes(imagePath, pngData);
}
/// <summary>
/// 图片尺寸大小缩放
/// </summary>
/// <param name="source"></param>
/// <param name="targetWidth"></param>
/// <param name="targetHeight"></param>
/// <returns></returns>
private Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
{
Texture2D result = new Texture2D(targetWidth, targetHeight, source.format, true);
UnityEngine.Color[] rpixels = result.GetPixels(0);
float incX = ((float)1 / source.width) * ((float)source.width / targetWidth);
float incY = ((float)1 / source.height) * ((float)source.height / targetHeight);
for (int px = 0; px < rpixels.Length; px++)
{
rpixels[px] = source.GetPixelBilinear(incX * ((float)px % targetWidth), incY * ((float)Mathf.Floor(px / targetWidth)));
}
result.SetPixels(rpixels, 0);
result.Apply();
return result;
}
public void OnSingletonInit()
{
}
}
}
插眼 : 2020/10/21 更新
1. 返回 在指定目录下加载的所有图片的 Texture2D
2. 文件 转 字节
3. 得到指定后缀格式的所有文件路径
4. 得到多个指定后缀格式的所有文件路径
5. 文件夹目录最多只保留指定数量的图片
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using System.Drawing;
namespace QFramework.Example
{
public class TextureKit:ISingleton
{
private TextureKit() { }
public static TextureKit Instance
{
get { return SingletonProperty<TextureKit>.Instance; }
}
/// <summary>
/// 返回 在指定目录下加载的所有图片的 Texture2D
/// </summary>
/// <returns></returns>
public List<Texture2D> LoadTexture2DToList(string sFold)
{
List<Texture2D> lLoadT2ds = new List<Texture2D>();
//获取到路劲
List<string> filePaths = new List<string>();
filePaths = GetImagesPath(sFold);
//新建时要给上大小,小于原先的图片大小会出现图片值截取一块的情况
//根据读取到的文件路径,一个文件一个文件的将图片存储进去
for (int i = 0; i < filePaths.Count; i++)
{
Image image = Image.FromStream(new MemoryStream(FileToBytes(filePaths[i])));
Texture2D t2d = new Texture2D(image.Width, image.Height);
//根据路劲读取字节流再转换成图片形式
t2d.LoadImage(FileToBytes(filePaths[i]));
//放到集合里面
lLoadT2ds.Add(t2d);
}
return lLoadT2ds;
}
/// <summary>
/// 文件 转 字节
/// </summary>
/// <param name="sFilePath"></param>
/// <returns></returns>
public static byte[] FileToBytes(string sFilePath)
{
//读取到文件
FileStream files = new FileStream(sFilePath, FileMode.Open);
//新建比特流对象
byte[] bArrFileBytes = new byte[files.Length];
//将文件写入对应比特流对象
files.Read(bArrFileBytes, 0, bArrFileBytes.Length);
//关闭文件
files.Close();
//返回比特流的值
return bArrFileBytes;
}
/// <summary>
/// 得到指定后缀格式的所有文件路径
/// 默认后缀为 "*.PNG"
/// </summary>
/// <returns></returns>
public List<string> GetImagesPath(string sFold, string sNameSuffix = "*.PNG")
{
List<string> filePaths = new List<string>();
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", sNameSuffix);
string[] dirs = Directory.GetFiles(sFold, sNameSuffix);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
//Debug.Log("图片路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "张图片");
return filePaths;
}
/// <summary>
/// 得到多个指定后缀格式的所有文件路径
/// Case : 需自己修改 imgtype按照格式去添加后缀格式
/// </summary>
/// <returns></returns>
public List<string> GetMultiNameSuffixFilePath(string sFold)
{
List<string> filePaths = new List<string>();
string imgtype = "*.JPG|*.PNG";
string[] ImageType = imgtype.Split('|');
for (int i = 0; i < ImageType.Length; i++)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
string[] dirs = Directory.GetFiles(sFold, ImageType[i]);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
Debug.Log("文件路径为 " + dirs[j]);
}
Debug.Log("一共读取到" + dirs.Length + "个文件");
}
return filePaths;
}
/// <summary>
/// 文件夹目录最多只保留指定数量的图片
/// sNameSuffix 后缀名
/// </summary>
public void DeleteWhenOverLoad(string sFoldPath, string sNameSuffix = "", int iFoldMaxSaveNum = 40)
{
//获取unity根目录下的图片文件夹下的所有文件的路径 路径+ 名称全部存储在字符串数组中
//string[] dirs = Directory.GetFiles(Application.streamingAssetsPath + "/BlendFaceImages", "*.PNG");
string[] dirs = Directory.GetFiles(sFoldPath, "*.PNG");
Log.I("文件夹目录大小 : " + dirs.Length);
//需要删除的数量
int iNeedDeleteNum = dirs.Length - iFoldMaxSaveNum;
if (iNeedDeleteNum > 0)
{
for (int i = 0; i < iNeedDeleteNum; i++)
{
File.Delete(dirs[i]);
Log.I("++++++++++++++ 文件被删除 +++++" + dirs[i]);
}
}
}
public void OnSingletonInit()
{
}
}
}