【问题标题】:How to resize and save a Texture2D in XNA?如何在 XNA 中调整和保存 Texture2D 的大小?
【发布时间】:2009-03-19 22:18:26
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# .net xna image-manipulation


    【解决方案1】:

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

    这个简单的例子展示了如何做到这一点。忽略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);
        }
    }
    

    【讨论】:

    • 这是最接近我最终实现的。虽然我没有使用 kernel32 导入或 GetConsoloWindow,但我只是使用了 Game 对象中的 GraphicsDevice。
    【解决方案2】:

    你试过Texture2D.Save()吗?

    【讨论】:

    • 如果 Texture2D 的大小正确,这将起作用,但缩放是通过 Draw 调用完成的,如何创建一个已缩放的 Texture2D 对象?
    【解决方案3】:

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

    当然,您可能正在编写 Zune 游戏,这意味着我可能对那里的缩放不感兴趣,但是,无论如何。

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

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

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

    【讨论】:

    • 我真的很想避免在游戏中缩放以保持我的碰撞代码简单。
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 2010-10-11
      • 1970-01-01
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多