【Unity3D / Texture】裁剪纹理 去除边缘空白部分

效果预览

裁剪之前:
【Unity3D / Texture】裁剪纹理 去除边缘空白部分_第1张图片
裁剪之后:
【Unity3D / Texture】裁剪纹理 去除边缘空白部分_第2张图片
左边,顶部,和右侧的空白部分,都去除了,因为适配窗口显示的原因,看上去图片变大了,实际尺寸是没变的。

思路

纹理的空白部分,即透明度为0的部分,那么,对图像的各个方向进行逐像素扫描,找出上下左右四个方向,最靠近内侧的,包含有效像素的行或者列的坐标,即可限定有效图像的区域,创建一个新纹理,拷贝出有效区域,即可。
【Unity3D / Texture】裁剪纹理 去除边缘空白部分_第3张图片
以下是裁剪出图像中所有透明度大于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;
            }
        }

补充说明

因为这是逐像素处理的,效率是比较低的,只适合做编辑器工具,或者是游戏启动加载阶段做预处理,不适合做实时处理使用。

你可能感兴趣的:(Unity3D)