0

当我在我的 XNA 游戏中制作屏幕截图时,每张都会texture.SaveAsPng消耗一些内存,并且似乎不会回到游戏中。所以最终我的内存不足。我尝试将纹理数据保存到FileStreamandMemoryStream中,希望可以从那里保存为Bitmap,但结果是一样的。有没有办法强制释放此内存或一些解决方法,让我获取图像数据并以其他方式保存它而不会遇到内存不足异常?

sw = GraphicsDevice.Viewport.Width;
sh = GraphicsDevice.Viewport.Height;

int[] backBuffer = new int[sw * sh];
GraphicsDevice.GetBackBufferData(backBuffer);
using(Texture2D texture = new Texture2D(GraphicsDevice, sw, sh, false,
  GraphicsDevice.PresentationParameters.BackBufferFormat))
{
    texture.SetData(backBuffer);
    using(var fs = new FileStream("screenshot.png", FileMode.Create))        
        texture.SaveAsPng(fs, sw, sh);  // ← this line causes memory leak      
}
4

1 回答 1

2

您也许可以直接从纹理字节创建位图并绕过内部方法来检查是否SaveAsPng泄漏或其他原因。

试试这个扩展方法(不幸的是我无法测试(没有 xna 在工作)但它应该可以工作。)

public static class TextureExtensions
{
    public static void TextureToPng(this Texture2D texture, int width, int height, ImageFormat imageFormat, string filename)
    {
        using (Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            byte blue;
            IntPtr safePtr;
            BitmapData bitmapData;
            Rectangle rect = new Rectangle(0, 0, width, height);
            byte[] textureData = new byte[4 * width * height];

            texture.GetData<byte>(textureData);
            for (int i = 0; i < textureData.Length; i += 4)
            {
                blue = textureData[i];
                textureData[i] = textureData[i + 2];
                textureData[i + 2] = blue;
            }
            bitmapData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            safePtr = bitmapData.Scan0;
            Marshal.Copy(textureData, 0, safePtr, textureData.Length);
            bitmap.UnlockBits(bitmapData);
            bitmap.Save(filename, imageFormat);
        }
    }
}

它有点粗糙,但你可以清理它(如果它甚至可以工作)。

最后但并非最不重要的一点(如果所有其他尝试都失败了)你可以打电话给GarbageCollection自己,但不建议这样做,因为它是非常糟糕的做法。

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

上面的代码应该是最后的手段。

祝你好运。

于 2013-01-14T01:27:53.057 回答