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轴是从左到右的,所以这会让你取到纹理右侧完全不相关的区域,自然得不到预期结果。
额外注意事项
- 纹理必须可读:在Unity编辑器中选中纹理,在Inspector的Import Settings里勾选
Read/Write Enabled,否则GetPixels()会抛出异常或者返回空数组。 - 如果是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
相关产品推荐
相关产品推荐

