我有XNA的另一个问题。我有一个包含许多图块的Texture2D。然后我有一个矩形列表,它应该是每个50x50像素磁贴的边界。
现在我希望能够将任何磁贴保存为一个小的PNG文件。 这是我的代码:
//declare the rectangles and spritesets
Texture2D tileSheet;
List<Rectangle> tileSet;
//load every tile, also works great
tileSheet = Content.Load<Texture2D>(@"Tiles/Object");
int noOfTilesX = (int)tileSheet.Width / 50;
int noOfTilesY = (int)tileSheet.Height / 50;
tileSet = new List<Rectangle>(noOfTilesX * noOfTilesY);
for (int j = 0; j < noOfTilesY; j++)
{
for (int i = 0; i < noOfTilesX; i++)
{
bounds = new Rectangle(i * 50, j * 50, 50, 50);
tileSet.Add(bounds);
}
}
//save as pngs if they do not exist
if (!File.Exists(@"C:\Test.png"))
{
Stream stream = File.Create(@"C:\Test.png");
//works, but it is only the complete file, i'd like to save a single tile
tileSheet.SaveAsPng(stream, tileSheet.Width, tileSheet.Height);
}
问题是:我无法保存单个图块,它总是保存我的整个Texture2D并将其拉伸到我在参数中传递的分辨率。在互联网上搜索没有告诉我什么,它只是告诉我如何使用流来获得完整的纹理2D。
答案 0 :(得分:1)
我刚刚回答了一个问题,其中某人想要通过采用更大纹理的一部分来获得新纹理,就像你的瓷砖问题一样。
您可以使用此扩展方法,然后像平常一样保存结果:
public static class TextureExtension
{
/// <summary>
/// Creates a new texture from an area of the texture.
/// </summary>
/// <param name="graphics">The current GraphicsDevice</param>
/// <param name="rect">The dimension you want to have</param>
/// <returns>The partial Texture.</returns>
public static Texture2D CreateTexture(this Texture2D src, GraphicsDevice graphics, Rectangle rect)
{
Texture2D tex = new Texture2D(graphics, rect.Width, rect.Height);
int count = rect.Width * rect.Height;
Color[] data = new Color[count];
src.GetData(0, rect, data, 0, count);
tex.SetData(data);
return tex;
}
}
建议用法:
using (FileStream stream = File.OpenWrite("path"))
{
tileTexture.CreateTexture(GraphicsDevice, new Rectangle(50, 50, 100, 100)).SaveAsJpeg(stream, 100, 100);
}
答案 1 :(得分:0)
尝试这样的事情。我没有对它进行测试,因此可能存在一些错误,但您只需为每个磁贴创建一个单独的纹理,然后保存每个纹理。
//declare the rectangles and spritesets
Texture2D tileSheet;
List<Rectangle> tileSet;
//load every tile, also works great
tileSheet = Content.Load<Texture2D>(@"Tiles/Object");
int noOfTilesX = (int)tileSheet.Width / 50;
int noOfTilesY = (int)tileSheet.Height / 50;
tileSet = new List<Rectangle>(noOfTilesX * noOfTilesY);
// Gets the color data of the tile sheet.
Color[] tileSheetPixels = new Color[tileSheet.Width * tileSheet.Height];
tileSheetPixels.GetData<Color>(tileSheetPixels);
for (int j = 0; j < noOfTilesY; j++)
{
for (int i = 0; i < noOfTilesX; i++)
{
bounds = new Rectangle(i * 50, j * 50, 50, 50);
tileSet.Add(bounds);
// Creates a new texture for a single tile.
Texture2D singleTile = new Texture2D(graphics, 50, 50);
Color[] pixels = new Color[50 * 50];
// Gets the pixels that correspond to the single tile and saves them in another
// color array.
for (int k = 0; k < pixels.Length; k++)
{
pixels[k] = new Color();
int x = bounds.X;
x += (k % 50);
int y = bounds.Y;
y += (k / 50);
pixels[k] = tileSheetPixels[y * 50 + x];
}
// Sets the color data of the single tile texture to the color array
// created above.
singleTile.SetData<Color>(pixels);
//save as pngs if they do not exist
if (!File.Exists(@"C:\tile_" + i + "_" + j + ".png"))
{
Stream stream = File.Create(@"C:\tile_" + i + "_" + j + ".png");
singleTile.SaveAsPng(stream, 50, 50);
}
}
}