效果预览
裁剪之前:
裁剪之后:
左边,顶部,和右侧的空白部分,都去除了,因为适配窗口显示的原因,看上去图片变大了,实际尺寸是没变的。
思路
纹理的空白部分,即透明度为0的部分,那么,对图像的各个方向进行逐像素扫描,找出上下左右四个方向,最靠近内侧的,包含有效像素的行或者列的坐标,即可限定有效图像的区域,创建一个新纹理,拷贝出有效区域,即可。
以下是裁剪出图像中所有透明度大于0 的部分的代码,根据实际需求,可以把透明度提取成参数动态调用,按需求过滤掉半透明的内容。
代码实现
public static Texture2D ClipBlank(Texture2D orgin)
{
try
{
var left = 0;
var top = 0;
var right = orgin.width;
var botton = orgin.height;
// 左侧
for (var i = 0; i < orgin.width; i++)
{
var find = false;
for (var j = 0; j < orgin.height; j++)
{
var color = orgin.GetPixel(i, j);
if (Math.Abs(color.a) > 1e-6)
{
find = true;
break;
}
}
if (find)
{
left = i;
break;
}
}
// 右侧
for (var i = orgin.width - 1; i >= 0; i--)
{
var find = false;
for (var j = 0; j < orgin.height; j++)
{
var color = orgin.GetPixel(i, j);
if (Math.Abs(color.a) > 1e-6)
{
find = true;
break;
}
}
if (find)
{
right = i;
break;
}
}
// 上侧
for (var j = 0; j < orgin.height; j++)
{
var find = false;
for (var i = 0; i < orgin.width; i++)
{
var color = orgin.GetPixel(i, j);
if (Math.Abs(color.a) > 1e-6)
{
find = true;
break;
}
}
if (find)
{
top = j;
break;
}
}
// 下侧
for (var j = orgin.height - 1; j >= 0; j--)
{
var find = false;
for (var i = 0; i < orgin.width; i++)
{
var color = orgin.GetPixel(i, j);
if (Math.Abs(color.a) > 1e-6)
{
find = true;
break;
}
}
if (find)
{
botton = j;
break;
}
}
// 创建新纹理
var width = right - left;
var height = botton - top;
var result = new Texture2D(width, height, TextureFormat.ARGB32, false);
result.alphaIsTransparency = true;
// 复制有效颜色区块
var colors = orgin.GetPixels(left, top, width, height);
result.SetPixels(0, 0, width, height, colors);
result.Apply();
return result;
}
catch (Exception e)
{
return null;
}
}
补充说明
因为这是逐像素处理的,效率是比较低的,只适合做编辑器工具,或者是游戏启动加载阶段做预处理,不适合做实时处理使用。