C# 使用Texture2D.SaveAsPng连续保存多个屏幕截图会导致内存不足异常
当我在XNA游戏中进行截图时,每个C# 使用Texture2D.SaveAsPng连续保存多个屏幕截图会导致内存不足异常,c#,xna,out-of-memory,C#,Xna,Out Of Memory,当我在XNA游戏中进行截图时,每个纹理.SaveAsPng都会消耗一些内存,而且似乎不会返回游戏。所以最终我的内存用完了。我尝试将纹理数据保存到FileStream和MemoryStream,希望可以将其保存为Bitmap,但结果相同。有没有一种方法可以强制释放这个内存,或者有一些解决方法可以让我获取图像数据并以其他方式保存它,而不会出现内存不足异常 sw = GraphicsDevice.Viewport.Width; sh = GraphicsDevice.Viewport.Height;
纹理.SaveAsPng
都会消耗一些内存,而且似乎不会返回游戏。所以最终我的内存用完了。我尝试将纹理数据保存到FileStream
和MemoryStream
,希望可以将其保存为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
}
您可以直接从纹理字节创建位图,并绕过内部方法来检查
SaveAsPng
是否泄漏或其他内容
尝试这种扩展方法(不幸的是,我无法测试(没有xna在工作),但它应该可以工作。)
以上代码应为最后手段
祝你好运。你能发布一个产生“内存泄漏”的小例子吗?你能显示保存纹理的代码吗?纹理是否
Texture2D
?我直接尝试了GC方法,但不幸的是没有成功。然后我用你的代码制作了108个屏幕截图,虽然花费了相当长的时间,但每4096×4096个图像的消耗量从未超过800兆字节。谢谢!谢谢你,这工作太完美了。SaveAsPng内存泄漏正在扼杀我的项目
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);
}
}
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();