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

如何缩放Sprite并后续使用(如另存为PNG)

问题解答

关于Sprite缩放的问题

首先明确:Unity的Sprite类没有scale属性,你贴的代码里sprite.scale = new Vector3(1,8,1);是错误写法,无法运行。

Transform的缩放仅修改渲染时的显示大小,不会改变Sprite对应的原始纹理像素。如果要真正修改Sprite的像素数据(生成缩放后的新纹理/Sprite),完全不需要依赖Transform,直接对Texture2D做像素级缩放处理即可。

你原来的代码思路有误——直接复制原纹理像素到新纹理,根本没有执行缩放逻辑,最终输出的还是原尺寸图片。要实现像素级缩放,需要对纹理进行重采样,推荐两种实用方式:

方式1:使用RenderTexture+Graphics.Blit缩放(高效)

// 加载原始纹理
Texture2D originalTex = new Texture2D(2, 2);
originalTex.LoadImage(File.ReadAllBytes(Path.Combine(Application.dataPath + "/Animation/raw/", "test.png")));

// 计算缩放后的目标尺寸(示例为Y轴放大8倍)
int targetWidth = originalTex.width;
int targetHeight = originalTex.height * 8;

// 创建临时RenderTexture作为缩放载体
RenderTexture rt = RenderTexture.GetTemporary(targetWidth, targetHeight);
rt.filterMode = FilterMode.Bilinear; // 缩放采样模式,可按需选Bilinear/Point

// 将原始纹理渲染到缩放后的RenderTexture
Graphics.Blit(originalTex, rt);

// 从RenderTexture读取像素生成新纹理
RenderTexture.active = rt;
Texture2D scaledTex = new Texture2D(targetWidth, targetHeight);
scaledTex.ReadPixels(new Rect(0, 0, targetWidth, targetHeight), 0, 0);
scaledTex.Apply();

// 释放资源
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(rt);

// 生成缩放后的Sprite
Sprite scaledSprite = Sprite.Create(scaledTex, new Rect(0,0,targetWidth,targetHeight), Vector2.one*0.5f);

// 保存为PNG文件
File.WriteAllBytes(Path.Combine(Application.dataPath, "/Animation/test_scaled.png"), scaledTex.EncodeToPNG());

方式2:手动重采样像素(适合自定义逻辑)

如果需要更精细的采样控制,可以手动计算每个目标像素对应的原纹理位置:

Texture2D originalTex = new Texture2D(2,2);
originalTex.LoadImage(File.ReadAllBytes(Path.Combine(Application.dataPath + "/Animation/raw/", "test.png")));

int targetWidth = originalTex.width;
int targetHeight = originalTex.height *8;
Texture2D scaledTex = new Texture2D(targetWidth, targetHeight);

for(int y=0; y<targetHeight; y++){
    // 计算当前目标Y对应的原纹理Y坐标
    float originalY = (float)y / 8f;
    for(int x=0; x<targetWidth; x++){
        Color color = originalTex.GetPixelBilinear((float)x/targetWidth, originalY/originalTex.height);
        scaledTex.SetPixel(x, y, color);
    }
}
scaledTex.Apply();
// 后续生成Sprite、保存的代码同方式1

关于Sprite合并的问题

用texture.SetPixel(x,y,color)是可行的,但效率极低,不适合纹理尺寸较大或合并多个Sprite的场景。更高效的做法是:

  1. 创建足够大的目标Texture2D,尺寸能容纳所有要合并的Sprite;
  2. 对每个Sprite,获取其对应的像素数组(需对应Sprite的rect区域);
  3. 计算该Sprite在目标纹理中的位置,用SetPixels一次性将整个像素块复制到对应区域;
  4. 所有Sprite处理完成后调用Apply()保存修改,最后导出为PNG。

示例代码:

// 假设已有待合并的Sprite列表List<Sprite> spritesToMerge
// 计算目标纹理总尺寸(示例为横向排列,可按需调整布局逻辑)
int totalWidth = spritesToMerge.Sum(s => (int)s.rect.width);
int maxHeight = spritesToMerge.Max(s => (int)s.rect.height);

Texture2D mergedTex = new Texture2D(totalWidth, maxHeight);
int currentX = 0;

foreach(Sprite sprite in spritesToMerge){
    int spriteWidth = (int)sprite.rect.width;
    int spriteHeight = (int)sprite.rect.height;
    // 获取Sprite对应的像素数组
    Color[] pixels = sprite.texture.GetPixels((int)sprite.rect.x, (int)sprite.rect.y, spriteWidth, spriteHeight);
    // 将像素块复制到目标纹理的对应位置
    mergedTex.SetPixels(currentX, 0, spriteWidth, spriteHeight, pixels);
    currentX += spriteWidth;
}

mergedTex.Apply();
// 保存合并后的纹理
File.WriteAllBytes(Path.Combine(Application.dataPath, "/Animation/merged.png"), mergedTex.EncodeToPNG());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 04:01:19