You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中使用Rect坐标获取纹理像素的问题求助

解决Unity中用Rect坐标获取纹理像素的问题

我来帮你排查问题并给出修复方案~你的核心问题是没完全理清UI Rect坐标系和Texture2D像素坐标系的差异,导致坐标转换逻辑出错了。

先明确坐标系差异

  • Unity UI的Rect(比如RectTransform的rect)默认原点在左上角,x轴从左到右递增,y轴从上到下递增。
  • Texture2D.GetPixels()的坐标原点在左下角,x轴同样从左到右递增,但y轴是从下到上递增。

你的代码错误主要出在水平方向的坐标转换上,垂直方向的逻辑其实是对的,但水平方向的反转完全没必要,反而导致取到了错误的区域。

正确的坐标转换代码

假设你的crop是从UI中获取的目标区域Rect(原点左上),正确的转换应该是这样:

// 确保你的纹理是可读的(在Import Settings里勾选Read/Write Enabled)
Texture2D texture = // 你的目标纹理
Rect crop = // 你要截取的UI区域Rect

// 转换UI坐标到Texture像素坐标
int texX = Mathf.RoundToInt(crop.x);
// 垂直方向:用纹理总高度减去UI的y偏移,再减去裁剪区域高度,得到Texture的y起始坐标
int texY = Mathf.RoundToInt(texture.height - crop.y - crop.height);
int cropWidth = Mathf.RoundToInt(crop.width);
int cropHeight = Mathf.RoundToInt(crop.height);

// 额外:添加边界校验,避免坐标超出纹理范围导致报错
texX = Mathf.Clamp(texX, 0, texture.width);
texY = Mathf.Clamp(texY, 0, texture.height);
cropWidth = Mathf.Clamp(cropWidth, 0, texture.width - texX);
cropHeight = Mathf.Clamp(cropHeight, 0, texture.height - texY);

// 现在可以正确获取像素了
Color[] pixels = texture.GetPixels(texX, texY, cropWidth, cropHeight);

为什么你的原代码不行?

你原代码的水平方向用了texture.width - (crop.width + crop.x),这相当于把x轴反转了——只有当你的UI坐标系x轴是从右往左递增时才需要这么做,但默认UI的x轴是从左到右的,所以这会让你取到纹理右侧完全不相关的区域,自然得不到预期结果。

额外注意事项

  1. 纹理必须可读:在Unity编辑器中选中纹理,在Inspector的Import Settings里勾选Read/Write Enabled,否则GetPixels()会抛出异常或者返回空数组。
  2. 如果是Sprite纹理:如果你是从UI的RawImage/Image组件的Sprite获取纹理,还要考虑Sprite在原始纹理中的偏移(sprite.textureRect),转换代码需要调整:
    Sprite targetSprite = rawImage.sprite;
    Rect crop = // 你的UI裁剪区域
    
    int texX = Mathf.RoundToInt(targetSprite.textureRect.x + crop.x);
    int texY = Mathf.RoundToInt(targetSprite.textureRect.y + (targetSprite.textureRect.height - crop.y - crop.height));
    int cropWidth = Mathf.RoundToInt(crop.width);
    int cropHeight = Mathf.RoundToInt(crop.height);
    
    // 同样添加边界校验
    texX = Mathf.Clamp(texX, 0, targetSprite.texture.width);
    texY = Mathf.Clamp(texY, 0, targetSprite.texture.height);
    cropWidth = Mathf.Clamp(cropWidth, 0, targetSprite.texture.width - texX);
    cropHeight = Mathf.Clamp(cropHeight, 0, targetSprite.texture.height - texY);
    
    Color[] pixels = targetSprite.texture.GetPixels(texX, texY, cropWidth, cropHeight);
    

内容的提问来源于stack exchange,提问作者UnknownUser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:12:59