将Pygame迁移至MonoGame:从大图裁剪生成Texture2D报错求助
解决MonoGame裁剪大图生成Texture2D的格式不兼容问题
错误原因
你遇到的System.ArgumentException是因为原纹理(大图)的像素格式与你创建的新Texture2D格式不匹配,导致GetData/SetData时数据类型(Color[])的字节大小和纹理实际像素的字节数不兼容。默认创建Texture2D时如果不指定格式,会用SurfaceFormat.Color,但你的大图可能是压缩格式(如DXT系列)或其他非Color格式,这时候用Color[]读取数据就会触发错误。
解决方案
方案1:匹配原纹理格式创建新纹理
创建新纹理时,直接复用原纹理的格式、MipMap设置,确保数据类型和纹理格式对应:
Texture2D sheet = texture; // 获取原纹理的关键参数 SurfaceFormat format = sheet.Format; bool hasMipMaps = sheet.LevelCount > 1; // 创建与原纹理格式一致的新纹理 Texture2D sprite = new Texture2D(game.Get_GraphicsDevice(), width, height, hasMipMaps, format); // 根据格式选择对应的数据类型 if (format == SurfaceFormat.Color) { Color[] data = new Color[width * height]; sheet.GetData(0, new Microsoft.Xna.Framework.Rectangle(x, y, width, height), data, 0, data.Length); sprite.SetData(data); } else { // 处理非Color格式,计算每个像素的字节数 int bytesPerPixel = format.GetBytesPerPixel(); byte[] data = new byte[width * height * bytesPerPixel]; sheet.GetData(0, new Microsoft.Xna.Framework.Rectangle(x, y, width, height), data, 0, data.Length); sprite.SetData(data); }
方案2:转为非压缩格式后裁剪(更通用)
如果原纹理是压缩格式,直接裁剪可能会有像素块对齐问题(比如DXT格式以4x4像素为压缩单元),建议先将整个大图转为非压缩的SurfaceFormat.Color,再提取目标区域:
Texture2D sheet = texture; // 读取整张大图的Color数据 Color[] fullSheetData = new Color[sheet.Width * sheet.Height]; sheet.GetData(fullSheetData); // 创建新的非压缩纹理 Texture2D sprite = new Texture2D(game.Get_GraphicsDevice(), width, height); Color[] spriteData = new Color[width * height]; // 复制目标区域的像素数据 for (int yOffset = 0; yOffset < height; yOffset++) { // 计算原大图中当前行的起始索引,复制width个像素到新纹理数据中 int sourceStartIndex = (y + yOffset) * sheet.Width + x; int targetStartIndex = yOffset * width; Array.Copy(fullSheetData, sourceStartIndex, spriteData, targetStartIndex, width); } sprite.SetData(spriteData);
注意事项
- 压缩纹理无法直接按任意矩形裁剪,必须先转为非压缩格式,否则会出现数据读取异常或显示错误。
- 如果你确定大图是
SurfaceFormat.Color格式,检查创建新纹理时是否误设置了其他参数,比如MipMap导致的尺寸不匹配。
内容的提问来源于stack exchange,提问作者Agustin Silva
相关产品推荐
相关产品推荐

