XNA 将单个图块保存为 PNG

XNA saving a single tile as PNG

我还有一个关于 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 并将其拉伸到我传入参数的分辨率。在网上搜索也没有告诉我什么,它只是告诉我如何使用流来获得一个完整的texture2D。

尝试这样的事情。我还没有测试过,所以可能会有一些错误,但你只需要为每个图块创建一个单独的纹理,然后保存它们中的每一个。

//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);
        }
    }
}

我刚刚回答了一个问题,其中有人想要通过获取更大纹理的一部分来获得新纹理,就像您的瓷砖问题一样。

您可以使用此扩展方法,然后像平常一样保存结果:

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);
}