图片裁剪
图片裁剪成圆形:
方法一:用圆形图片做底,用Mask组件去做,但是太蠢了,看看就行了。
方法二:重写Image的OnPopulateMesh(VertexHelper vh)方法
链接:https://zhuanlan.zhihu.com/p/386569362
计算机不识别圆形,只能识别三角形,故圆形是通过多个三角形实现的,圆中三角形越多,我们看到的形状就越接近于圆。
OnPopulateMesh(VertecHelper vh):
我们可以通过这个方法,获取或者修改顶点的数据。
VertexHelper:
用于存储绘制图形的顶点信息的载体,GPU会根据其中参数中的信息进行图形绘制。
UV:
uv是一种二维坐标信息,可以简单看作是四维向量(x, y, z, w)
如上图所示,一个坐标系中的矩形可以通过x,y,z,w四个数字来表示,但由于系统底层需要使用UV坐标进行绘制,所以我们需要把图片的位置信息转换成UV坐标。
Vector2 uv = new Vector2(z - x, w - y);
脚本如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImageClip : Image
{
[SerializeField]
private int m_iSegments = 100;
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
float width = rectTransform.rect.width;
float height = rectTransform.rect.height;
Vector2 uv = new Vector2(1, 1);//单一图片 不能放进图集
Vector2 convertRatio = GetConvertRatio(uv.x, uv.y, width, height);
Vector2 uvCenter = GetUVCenter(uv.x, uv.y);
Vector2 originPos = GetOriginPos(width, height);
UIVertex origin = new UIVertex();
origin.position = originPos;
origin.uv0 = new Vector2(Vector2.zero.x * convertRatio.x + uvCenter.x, Vector2.zero.y * convertRatio.y + uvCenter.y);
origin.color = new Color32(255, 255, 255, 255);
vh.AddVert(origin);//将圆心作为所有组成圆的三角形的顶点,且时第一个存入vh中,id为0
float radian = Mathf.PI * 2 / m_iSegments;
float curRadian = 0;
float radius = width * 0.5f;
for(int i = 0; i < m_iSegments + 1; i++)
{
float x = Mathf.Cos(curRadian) * radius;
float y = Mathf.Sin(curRadian) * radius;//此处根据勾股定理的几何定义,可以得到三角形的每个圆上顶点的坐标
curRadian += radian;
Vector2 xy = new Vector2(x, y);
UIVertex uvTemp = new UIVertex();
uvTemp.position = xy + originPos;
uvTemp.uv0 = new Vector2(xy.x * convertRatio.x + uvCenter.x, xy.y * convertRatio.y + uvCenter.y);
uvTemp.color = new Color32(255, 255, 255, 255);
vh.AddVert(uvTemp);
}
int id = 1;
for(int i = 0; i < m_iSegments; i++)
{
vh.AddTriangle(id, 0, id + 1);
id++;
}
}
private Vector2 GetUVCenter(float uvWidth, float uvHeight)
{
Vector2 center = new Vector2(uvWidth * 0.5f, uvHeight * 0.5f);
return center;
}
private Vector2 GetConvertRatio(float uvWidth, float uvHeight, float width, float height)
{
Vector2 convertRatio = new Vector2(uvWidth / width, uvHeight / height);
return convertRatio;
}
private Vector2 GetOriginPos(float width, float height)
{
Vector2 originPos = new Vector2(width * (0.5f - rectTransform.pivot.x), height * (0.5f - rectTransform.pivot.y));
return originPos;
}
}