【个人笔记】图片裁剪 OnPopulateMesh(VertexHelper)

图片裁剪
图片裁剪成圆形:
方法一:用圆形图片做底,用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;
}

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值