赞
踩
最近项目内接到一个需求,使用工具将序列帧转化为Texture。研究了一波,发现unity本身可以实现,于是有了这个东西。
先说一下思路:直接从文件夹读取到需要操作的图片,然后将图片依次写入一张新建的Texture。
废话不多说,直接上代码
以下为从文件夹读取到jpg的图片,然后通过FileStream转换成Texture2D。(以下为测试使用,部分参数未规范化,请轻喷...)
- [MenuItem("Tools/合并多张图片", false, 4)]
- public static void Test()
- {
- string path = Application.dataPath + "/sucai";
- Debug.Log(path);
- DirectoryInfo folder = new DirectoryInfo(path);
- var files = folder.GetFiles("*.jpg");
- Debug.Log("files count :" + files.Length);
- Texture2D[] texture2Ds = new Texture2D[files.Length];
- int count = files.Length;
- for (int i = 0; i < files.Length; i++)
- {
- Debug.Log(files[i].Name);
- //EditorUtility.DisplayProgressBar("合并图片--->" + files[i].Name, "0%", i / count);
- FileStream fs = new FileStream(path + "/" + files[i].Name, FileMode.Open, FileAccess.Read);
- int byteLength = (int)fs.Length;
- byte[] imgBytes = new byte[byteLength];
- fs.Read(imgBytes, 0, byteLength);
- fs.Close();
- fs.Dispose();
- //因为懒得去写比例,所以直接将原图尺寸写入了
- Texture2D t2d = new Texture2D(1280, 720);
- ///这一步会将图片转换成实际大小
- t2d.LoadImage(imgBytes);
- t2d.Apply();
- texture2Ds[i] = t2d;
- //Color col = t2d.GetPixel(t2d.width / 2, t2d.height / 2);
- //Debug.Log(col);
- }
- Texture2D tex = MergeMoreTex(texture2Ds);
- byte[] bytes = tex.EncodeToPNG();
- //File.WriteAllBytes(Application.dataPath + "/out.png", bytes);
- EditorUtility.ClearProgressBar();
- EditorApplication.ExecuteMenuItem("Assets/Refresh");
- }
以下部分为将多个Texture2D对象写入一张大图,大图的尺寸我用的4096*4096。因为给我的图片尺寸本身不标准,所以写完后拿到的图最后会有空缺的部分。
- public static Texture2D MergeMoreTex(Texture2D[] texs)
- {
- if (texs.Length < 1) return null;
- Texture2D nTex = new Texture2D(4096, 4096, TextureFormat.ARGB32, true);
- Color[] colors = new Color[nTex.width * nTex.height];
- int startw, starth;
- startw = 0;//横向写入偏移
- starth = 0;//纵向写入偏移
- //以下计算横向跟纵向个数可能会出现大部分空余,这里的计算能满足我自己的需求,没有测试过复杂情况。有需要可以修改
- //根据数量计算横向个数
- int wcnt = Mathf.CeilToInt(Mathf.Sqrt(texs.Length / 1.8f));
- //纵向个数
- int hcnt = Mathf.FloorToInt(wcnt * (1280f / 720f));
- //单张高度
- int oneh = Mathf.FloorToInt(4096 / hcnt);
- //单张宽度
- int onew = Mathf.FloorToInt(4096 / wcnt);
- for (int i = 0; i < texs.Length; i++)
- {
- for (int h = 0; h < oneh; h++)
- {
- for (int w = 0; w < onew; w++)
- {
- Color color = texs[i].GetPixelBilinear((float)w / onew, (float)h / oneh);
- int index = h * nTex.width + w + startw + (starth * 4096);
- if(index >= colors.Length)
- {
- Debug.LogError("数组越界");
- continue;
- }
- if (colors[index] == null)
- {
- colors[index] = color;
- continue;
- }
- colors[index] = color;
- }
-
- }
- startw += onew;
- if(startw + onew > 4096)
- {
- starth += oneh;
- startw = 0;
- }
- }
- nTex.SetPixels(colors);
- nTex.Apply();
- return nTex;
- }
以上就是所有的东西了,然后附上效果图(截图)
因之前没有操作过这一块的东西,欢迎指出不足之处~。
噢,对了。这个没法支持不透明的图~
更新:具体计算单张图占比以及大小有问题,只需要看思路好了...
请看后续:Unity之合并多张图片为一张大图(二)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。