2013-01-14 36 views
0

的。当我在XNA游戏截图做,每个texture.SaveAsPng占用一些内存,它似乎并没有返回到游戏。所以最终我耗尽了内存。我试过纹理数据保存到FileStreamMemoryStream,希望我可以从那里保存为Bitmap,但结果是一样的。有没有办法来强制释放此内存或者一些解决方法,可以让我得到的图像数据,并保存它,而不会在内存溢出异常一些其他的方式?挽救了许多截图依次用Texture2D.SaveAsPng导致内存不足的异常

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  
} 
+0

你能张贴生产的“内存泄漏”的小例子吗? –

+0

你可以在保存纹理的地方显示代码吗? –

+0

纹理'Texture2D'? –

回答

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

上面的代码应该是LAST度假村只。

祝你好运。

+0

我直接前进,尝试了GC方法,但不幸的是没有工作。 – user1306322

+0

然后我做了108个截图与您的代码,并没有消耗过每4096超过800兆字节×4096的图像,虽然它花费了相当长的一段时间。非常感谢! – user1306322

+0

谢谢,这项工作很完美。 SaveAsPng内存泄漏正在造成我的项目 –