如何使用?
界面展示:
介绍: 是一个脚本(从别人源码改进了一点点)
作用:(√这么多好处,那为什么不用呢?)
1.对多张贴图进行通道选择,然后在指定文件夹目录创建并制成一张复合贴图
①对减少贴图资源有大用!(省资源)
②不用出去PS那么麻烦制作复合贴图了,泪目(省时间)
2.如果想单纯缩放图片,不在意图片有点损耗的话,可以通过此方式缩放图片
操作如下:
①把脚本拖入任何一个GameObject(游戏物体中)
②把图片拖入,选择好“相关选项”
③右键脚本处,可选择“选择保存路径”即可定位保存路径(自己输入也行)
④右键脚本出,选择“制作复合图像并保存”即可完成操作
代码模块
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System.IO;
public class CombineIntoCompositeMap : MonoBehaviour
{
public enum Channel
{
取R通道 = 0,
取G通道 = 1,
取B通道 = 2,
取A通道 = 3
};
public enum RGB_To_Gray_Mode
{
平均值法 = 0,
OpenCV彩色转灰度 = 1
}
[Header("请为RGBA通道选择相应图像")]
public Texture2D texR;//第一张拖入图
public Channel texRChannel = Channel.取R通道;
public Texture2D texG;//第二张拖入图
public Channel texGChannel = Channel.取R通道;
public Texture2D texB;//第三张拖入图
public Channel texBChannel = Channel.取R通道;
public Texture2D texA;//第四张拖入图
public Channel texAChannel = Channel.取R通道;
[Header("输出图片尺寸(像素)")]
public Vector2 imageWH = new Vector2(256,256);//自定义图片宽高
[Header("带A通道?")]
public bool isAlpha = true;//是否开启A通道
[Header("输出黑白图?")]
public bool isBlackAndWhite = false;//是否为黑白图
[Header("输出黑白图模式选择")]
public RGB_To_Gray_Mode GrayMode = RGB_To_Gray_Mode.平均值法;
[Header("输出图片名称")]
public string texName = "Enter Your Name!";//最终图片名称
[Header("输出图片路径")]
public string customPath = "";//目标路径
//[Header("尾部命名序号(自动+1);指定序号覆盖原数据")]
//public int serial = 1;
[Header("图片后缀")]
public string suffix = "_Combined";
[Header("在此材质上看效果")]
public Material mat;
public string matTexName = "_MainTex";
private Texture2D texAllCombined;//所有图片结合体
private Color[] colorR;//TexR临时颜色
private Color[] colorG;//TexG临时颜色
private Color[] colorB;//TexB临时颜色
private Color[] colorA;//TexA临时颜色
private Color[] colorAllCombined;//最终输出相关颜色
private Texture2D R;
private Texture2D G;
private Texture2D B;
private Texture2D A;
void SetTexImport(Texture2D inputTex)//修改Texture2D导入设置
{
string path = AssetDatabase.GetAssetPath(inputTex);
TextureImporter tex = AssetImporter.GetAtPath(path) as TextureImporter;
//存储 TextureImporter 的平台特定设置。
TextureImporterPlatformSettings set = new TextureImporterPlatformSettings();
tex.isReadable = true;//允许读取纹理数据
AssetDatabase.ImportAsset(path);
set.format = TextureImporterFormat.RGBA32;
tex.SetPlatformTextureSettings(set);
//重新导入资源,否则更改并未生效
//如资源未执行重新导入,则会在项目保存时自动导入、生效
AssetDatabase.ImportAsset(path);
}
void Save(Color[] colors)//创建图像并保存为基础图像
{
TextureFormat _texFormat;
if (isAlpha){
_texFormat = TextureFormat.ARGB32;
}else{
_texFormat = TextureFormat.RGB24;
}
Texture2D tex = new Texture2D((int)imageWH.x, (int)imageWH.y, _texFormat, false);//创建特定宽高图片
tex.SetPixels(colors);
tex.Apply();//实际应用任何先前的 SetPixel 和 SetPixels 更改
byte[] bytes;
bytes = tex.EncodeToPNG();//转化为.PNG图片(返回byte[])
//①序号方式
//string fileName = texName + "_" + serial;
//serial += 1;
//②后缀方式
string fileName = texName + "_" + suffix;
//创建新文件,将指定字节数组写入此文件(如文件已存在,则会覆盖)
File.WriteAllBytes(customPath + "/" + fileName + ".png", bytes);
Debug.Log("PNG图像:" + fileName + "已保存到" + customPath);
AssetDatabase.Refresh();//导入所有更改资源
}
void SetTexSize()//设置图片尺寸
{
if(texR != null)
{
Debug.Log("texR!=null");
SetTexImport(texR);//修改Tex导入设置
R = texR;
string path = AssetDatabase.GetAssetPath(R);
R = ScaleTexture(texR, imageWH.x, imageWH.y);//将双线性过滤后的缩放图像 赋值给R
R.Apply();//实际应用任何先前的 SetPixel 和 SetPixels 更改
TextureImporter tex = AssetImporter.GetAtPath(path) as TextureImporter;
TextureImporterPlatformSettings temp = new TextureImporterPlatformSettings();
temp.format = TextureImporterFormat.Automatic;
tex.SetPlatformTextureSettings(temp);
tex.isReadable = false;
AssetDatabase.ImportAsset(path);
}
if (texG != null)
{
SetTexImport(texG);//修改Tex导入设置
G = texG;
string path = AssetDatabase.GetAssetPath(G);
G = ScaleTexture(texG, imageWH.x, imageWH.y);//将双线性过滤后的缩放图像 赋值给G
G.Apply();//实际应用任何先前的 SetPixel 和 SetPixels 更改
TextureImporter tex = AssetImporter.GetAtPath(path) as TextureImporter;
TextureImporterPlatformSettings temp = new TextureImporterPlatformSettings();
temp.format = TextureImporterFormat.Automatic;
tex.SetPlatformTextureSettings(temp);
tex.isReadable = false;
AssetDatabase.ImportAsset(path);
}
if (texB != null)
{
SetTexImport(texB);//修改Tex导入设置
B = texB;
string path = AssetDatabase.GetAssetPath(B);
B = ScaleTexture(texB, imageWH.x, imageWH.y);//将双线性过滤后的缩放图像 赋值给B
B.Apply();//实际应用任何先前的 SetPixel 和 SetPixels 更改
TextureImporter tex = AssetImporter.GetAtPath(path) as TextureImporter;
TextureImporterPlatformSettings temp = new TextureImporterPlatformSettings();
temp.format = TextureImporterFormat.Automatic;
tex.SetPlatformTextureSettings(temp);
tex.isReadable = false;
AssetDatabase.ImportAsset(path);
}
if (texA != null)
{
SetTexImport(texA);//修改Tex导入设置
A = texA;
string path = AssetDatabase.GetAssetPath(A);
A = ScaleTexture(texA, imageWH.x, imageWH.y);//将双线性过滤后的缩放图像 赋值给A
A.Apply();//实际应用任何先前的 SetPixel 和 SetPixels 更改
TextureImporter tex = AssetImporter.GetAtPath(path) as TextureImporter;
TextureImporterPlatformSettings temp = new TextureImporterPlatformSettings();
temp.format = TextureImporterFormat.Automatic;
tex.SetPlatformTextureSettings(temp);
tex.isReadable = false;
AssetDatabase.ImportAsset(path);
}
}
[ContextMenu("制作复合图像并保存")]
void CombineImage()
{
colorR = new Color[0];
colorG = new Color[0];
colorB = new Color[0];
colorA = new Color[0];
colorAllCombined = new Color[0];
SetTexSize();//设置图片尺寸
texAllCombined = new Texture2D((int)imageWH.x, (int)imageWH.y);//图片通道结合体
//将图像像素颜色信息赋给color[]
if (texR != null)
{
colorR = R.GetPixels();
colorAllCombined = R.GetPixels();
}
if (texG != null)
{
colorG = G.GetPixels();
}
if (texB != null)
{
colorB = B.GetPixels();
}
if (texA != null)
{
colorA = A.GetPixels();
}
//通道选取
for (int i = 0; i < imageWH.x * imageWH.y; i++)
{
//最终图像R通道 = TexR的选定Channel
if (texR != null)
{
if (texRChannel == Channel.取R通道)
{
colorAllCombined[i].r = colorR[i].r;
}
if (texRChannel == Channel.取G通道)
{
colorAllCombined[i].r = colorR[i].g;
}
if (texRChannel == Channel.取B通道)
{
colorAllCombined[i].r = colorR[i].b;
}
if (texRChannel == Channel.取A通道)
{
colorAllCombined[i].r = colorR[i].a;
}
}else { colorAllCombined[i].r = 0.0f; }
//最终图像G通道 = TexG的选定Channel
if (texG != null)
{
if (texGChannel == Channel.取R通道)
{
colorAllCombined[i].g = colorG[i].r;
}
if (texGChannel == Channel.取G通道)
{
colorAllCombined[i].g = colorG[i].g;
}
if (texGChannel == Channel.取B通道)
{
colorAllCombined[i].g = colorG[i].b;
}
if (texGChannel == Channel.取A通道)
{
colorAllCombined[i].g = colorG[i].a;
}
}else { colorAllCombined[i].g = 0.0f; }
//最终图像B通道 = TexB的选定Channel
if (texB != null)
{
if (texBChannel == Channel.取R通道)
{
colorAllCombined[i].b = colorB[i].r;
}
if (texBChannel == Channel.取G通道)
{
colorAllCombined[i].b = colorB[i].g;
}
if (texBChannel == Channel.取B通道)
{
colorAllCombined[i].b = colorB[i].b;
}
if (texBChannel == Channel.取A通道)
{
colorAllCombined[i].b = colorB[i].a;
}
}else { colorAllCombined[i].b = 0.0f; }
//最终图像A通道 = TexA的选定Channel
if (texA != null)
{
if (texAChannel == Channel.取R通道)
{
colorAllCombined[i].a = colorA[i].r;
}
if (texAChannel == Channel.取G通道)
{
colorAllCombined[i].a = colorA[i].g;
}
if (texAChannel == Channel.取B通道)
{
colorAllCombined[i].a = colorA[i].b;
}
if (texAChannel == Channel.取A通道)
{
colorAllCombined[i].a = colorA[i].a;
}
}else { colorAllCombined[i].a = 0.0f; }
}
//是否为黑白图
if (isBlackAndWhite)
{
if(GrayMode == RGB_To_Gray_Mode.平均值法)//①平均值法
{
Color[] temp = colorAllCombined;//每个像素颜色
List<float> t = new List<float>();//创建List(用于暂时装载颜色值)
for (int j = 0; j < temp.Length; j++)
{
t.Add(temp[j].r * 0.33334f + temp[j].g * 0.33334f + temp[j].b * 0.33334f);
colorAllCombined[j].r = t[j];
colorAllCombined[j].g = t[j];
colorAllCombined[j].b = t[j];
}
}
if(GrayMode == RGB_To_Gray_Mode.OpenCV彩色转灰度)//②OpenCV彩色图转灰度图
{
Color[] temp = colorAllCombined;
List<float> t = new List<float>();
for (int j = 0; j < temp.Length; j++)
{
//简化版(0.3,0.59,0.11)
t.Add((temp[j].r * 0.299f + temp[j].g * 0.587f + temp[j].b * 0.114f));
colorAllCombined[j].r = t[j];
colorAllCombined[j].g = t[j];
colorAllCombined[j].b = t[j];
}
}
}
//最终输出
if (texR != null || texG != null || texB != null || texA != null)
{
texAllCombined.SetPixels(colorAllCombined);
texAllCombined.Apply();
if (mat != null)
{
mat.SetTexture(matTexName, texAllCombined);
Debug.Log("贴图已同步赋予到材质 以查看效果");
}
Save(colorAllCombined);
}
}
//-------------------非主要附加函数-----------------
Texture2D ScaleTexture(Texture2D source, float targetWidth, float targetHeight)//缩放图像(经过双线性过滤)
{
Texture2D result = new Texture2D((int)targetWidth, (int)targetHeight, source.format, false);
float incX = (1.0f / targetWidth);
float incY = (1.0f / targetHeight);
for (int i = 0; i < result.height; ++i)
{
for (int j = 0; j < result.width; ++j)
{
Color newColor = source.GetPixelBilinear((float)j / (float)result.width, (float)i / (float)result.height);
result.SetPixel(j, i, newColor);
}
}
result.Apply();
return result;
}
[ContextMenu("选择保存路径")]
void ChooseSavePath()
{
customPath = EditorUtility.OpenFolderPanel("", "", "");
}
}