C# 如何在 XNA 中调整和保存 Texture2D?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/664279/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:24:59  来源:igfitidea点击:

How to resize and save a Texture2D in XNA?

c#.netxnaimage-manipulation

提问by Ben S

In a level editor I've made for my XNA game (editor is also in XNA) I'm allowing to scale Texture2Dobjects.

在我为 XNA 游戏制作的关卡编辑器中(编辑器也在 XNA 中),我允许缩放Texture2D对象。

When the user tries to save the level, I'd like to actually resize the image file on disk so that it doesn't require scaling in the game.

当用户尝试保存关卡时,我想实际调整磁盘上图像文件的大小,以便它不需要在游戏中进行缩放。

Is there an easy way to create an image file (PNG preferred) from a scaled Texture2D object?

有没有一种简单的方法可以从缩放的 Texture2D 对象创建图像文件(首选 PNG)?

采纳答案by Leaf Garland

You can scale your textures by rendering to a render target at the size you want and then saving the render target texture.

您可以通过以所需大小渲染到渲染目标,然后保存渲染目标纹理来缩放纹理。

This simple example shows how you could do that. Ignore the setup of the GraphicsDevice, that's just to make a small self-contained example. The interesting bit is creating the render target and drawing the scaled texture. You should reuse the render targets where you can (all images of the same size can reuse a render target).

这个简单的例子展示了如何做到这一点。忽略 GraphicsDevice 的设置,这只是做一个独立的小例子。有趣的一点是创建渲染目标并绘制缩放纹理。您应该尽可能重用渲染目标(所有相同大小的图像都可以重用渲染目标)。

using System;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetConsoleWindow();

    static void Main(string[] args)
    {
        string sourceImagePath = args[0];
        string destinationImagePath = args[1];
        int desiredWidth = int.Parse(args[2]);
        int desiredHeight = int.Parse(args[3]);

        GraphicsDevice graphicsDevice = new GraphicsDevice(
            GraphicsAdapter.DefaultAdapter,
            DeviceType.Hardware,
            GetConsoleWindow(),
            new PresentationParameters());
        SpriteBatch batch = new SpriteBatch(graphicsDevice);

        Texture2D sourceImage = Texture2D.FromFile(
            graphicsDevice, sourceImagePath);

        RenderTarget2D renderTarget = new RenderTarget2D(
            graphicsDevice, 
            desiredWidth, desiredHeight, 1, 
            SurfaceFormat.Color);

        Rectangle destinationRectangle = new Rectangle(
            0, 0, desiredWidth, desiredHeight);

        graphicsDevice.SetRenderTarget(0, renderTarget);

        batch.Begin();
        batch.Draw(sourceImage, destinationRectangle, Color.White);
        batch.End();

        graphicsDevice.SetRenderTarget(0, null);

        Texture2D scaledImage = renderTarget.GetTexture();
        scaledImage.Save(destinationImagePath, ImageFileFormat.Png);
    }
}

回答by xian

Have you tried Texture2D.Save()?

你试过Texture2D.Save()吗?

回答by Navaar

Scaling images generally does not incur all that much overhead, plus, you wouldn't want to load different sizes of the same texture into memory as that would be a waste.

缩放图像通常不会产生那么多开销,此外,您不希望将不同大小的相同纹理加载到内存中,因为这会造成浪费。

Of course, you could be writing a Zune game, which means I'm probably off about the scaling there, but, anyway.

当然,您可能正在编写 Zune 游戏,这意味着我可能不知道那里的缩放比例,但是,无论如何。

I don't think you can save the scaled image directly from XNA, but, you could use WinForms Image class to load the image and then scale it to the dimensions in your level editor and save it back out to disk.

我认为您不能直接从 XNA 保存缩放后的图像,但是,您可以使用 WinForms Image 类来加载图像,然后在关卡编辑器中将其缩放到尺寸并将其保存回磁盘。

If your texture isn't a BMP or PNG though, you may have to use the Texture2D.Save() command to convert it into a format you can use in the Image class.

如果您的纹理不是 BMP 或 PNG,您可能必须使用 Texture2D.Save() 命令将其转换为可以在 Image 类中使用的格式。

This thread might help you with using the Image class. http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/6fe3d353-0b09-440b-95c9-701efdc9e20a/

该线程可能会帮助您使用 Image 类。 http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/6fe3d353-0b09-440b-95c9-701efdc9e20a/

回答by Leaf Garland

I have code like this that makes a larger/smaller copy of a texture but I get errors after a while. After 30 resizes then I get the exception, not the first time.

我有这样的代码可以制作更大/更小的纹理副本,但一段时间后我会出错。调整大小 30 次后,我得到了异常,而不是第一次。

Seems to be a rendertarget problem but I am not sure. Wonder if you will get these exceptions too if you run this code a lot too?

似乎是渲染目标问题,但我不确定。想知道如果您也经常运行此代码,是否也会遇到这些异常?