unity3d任意图片截取和裁剪

楼主遇到打包获取的图片去截取一部分去贴图,这个问题令人费解,刚开始我想出的办法是采集像素点去拼接成这个截取的部分,可是当做完后在楼主愉快的心情去运行到ipad上发现,卡巴斯基了(卡死了),其实想想也是这种循环获取像素点,不卡死那是神器啊,ipad air都运行不了的,更别说其他的神器了,虽然我最后没用这种办法,但是代码贴上去,大家可以参考一下

Texture2D ScaleTextureCutOut(Texture2D originalTexture, float originalWidth,float originalHeight)
	{
		Texture2D newTexture = new Texture2D(Mathf.CeilToInt (originalWidth), Mathf.CeilToInt (originalHeight));
		int maxX = originalTexture.width - 1;
		int maxY = originalTexture.height - 1;
		for (int y = 0; y < newTexture.height; y++)
		{
			for (int x = 0; x < newTexture.width; x++)
			{
				float targetX = x ;
				float targetY = y ;
				int x1 = Mathf.Min(maxX, Mathf.FloorToInt(targetX));
				int y1 = Mathf.Min(maxY, Mathf.FloorToInt(targetY));
				int x2 = Mathf.Min(maxX, x1 + 1);
				int y2 = Mathf.Min(maxY, y1 + 1);
				
				float u = targetX - x1;
				float v = targetY - y1 ;
				float w1 = (1 - u) * (1 - v);
				float w2 = u * (1 - v);
				float w3 = (1 - u) * v;
				float w4 = u * v;
				Color color1 = originalTexture.GetPixel(x1, y1);
				Color color2 = originalTexture.GetPixel(x2, y1);
				Color color3 = originalTexture.GetPixel(x1, y2);
				Color color4 = originalTexture.GetPixel(x2,  y2);
				Color color = new Color(Mathf.Clamp01(color1.r * w1 + color2.r * w2 + color3.r * w3+ color4.r * w4),
				                        Mathf.Clamp01(color1.g * w1 + color2.g * w2 + color3.g * w3 + color4.g * w4),
				                        Mathf.Clamp01(color1.b * w1 + color2.b * w2 + color3.b * w3 + color4.b * w4),
				                        Mathf.Clamp01(color1.a * w1 + color2.a * w2 + color3.a * w3 + color4.a * w4)
				                        );
				newTexture.SetPixel(x, y, color);
			}
		}
		newTexture.anisoLevel = 2;
		newTexture.Apply();
		return newTexture;
	}

传入你的那张贴图,或者资源,即可,后边两个参数,长和宽,代码我就不解释了,很简单的一个算法,但是大家要注意一个方法,GetPixel这个方法,在 Inspector里设置两个属性才可以使用,

TextureType:Advanced;

Non Power of 2:None; 

Read/Write Enabled:true;

才可以正常使用,也可以用代码去设置Inspector的属性

string path = AssetDatabase.GetAssetPath(tex); 
		TextureImporter texImporter= AssetImporter.GetAtPath(path) as TextureImporter; 
		texImporter.npotScale = TextureImporterNPOTScale.None;
		texImporter.isReadable = true;
		AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);

这个方法设置属性,要导入头文件,这是编辑器类,导入using UnityEditor;

最后说说我用的办法,UV贴图,直接去改变mesh.uv的二维数值,以前我感觉这个和mesh.vertices是相对应的,后来楼主经过测试惊讶的发现,原来显示的图mesh.uv跟值的范围有关系,在uv的点在new Vector2(1,1)这个范围内它是取一张图的,范围的大小取决于取出来的图的大小,大家可以自己测试一下,我经过测试努力,解决了规则和不规则的贴图比例,可以贴出任意一张图,任意区间的截图,做这个刚开始楼主就想到用uv贴图了去算了,但是比较懒,没有用这种方法,就任意百度谷歌,结果试了很多种办法,都是失败告终,最后回归自己老本行,也就是我之前发过的两篇博客,uv贴图,把所有点等比例缩放到new Vector2(1,1)范围内,就可以实现了,也可多张贴图。

代码奉上,测试用例仅供参考

void SetUv1(Mesh mesh,float wight,float length,Texture2D tex) {
//Debug.LogError(length+"==="+wight+"==="+tex.width+"==="+tex.height);
Vector3[] vertices = new Vector3[4];
vertices[0] = new Vector3(0, 0, 0);
vertices[1] = new Vector3(0, 1, 0);
vertices[2] = new Vector3(-1, 1, 0);
vertices[3] = new Vector3(-1, 0, 0);
mesh.vertices = vertices;
int[] triangles = new int[6];
triangles[0] = 1;
triangles[1] = 0;
triangles[2] = 3;
triangles[3] = 2;
triangles[4] = 1;
triangles[5] = 3;
mesh.triangles = triangles;
Vector2 uvPostion0 = new Vector2(0, 0);
Vector2 uvPostion1 = new Vector2(0, length/tex.height);
Vector2 uvPostion2 = new Vector2(wight/tex.width,length/tex.height);
Vector2 uvPostion3 = new Vector2(wight/tex.width, 0);
mesh.uv = new Vector2[] { uvPostion0, uvPostion1, uvPostion2, uvPostion3 };   
}

这个方法针对规则四方形贴图,

因为我多边形代码算法写的特别杂乱,不好贴上了,如果大家对多边形算法有做不出来的,随时可以交流

提示一下

uvpoints[i] = new Vector2((uvpoints[i].x/(float)maxx)*(wight/tex.width),(uvpoints[i].y/(float)maxz)*(length/tex.height));

主要用这一句话返回这个mesh.uv这个数组,解释一下,之所以用uvpoint[i].x/maxx;是因为得出这个点集内最大的x点去缩放,这样保证点集内所有的点都在new Vector2(1,1)这个范围内,*(wight/tex.width)是你想截取这个图的宽度比例。

你可能感兴趣的:(unity)