Texture2d.SaveAsPng() Memory Leak

白昼怎懂夜的黑 提交于 2020-01-05 10:18:47

问题


I have found strange issue with method Texture2d.SaveAsPng() Every call 1.5mb disapear. I use this method to save texture to isolated storage

public static void SaveTextureToISF(string fileName, Texture2D texture)
        {
            using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (
                    IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream(fileName, FileMode.Create, file)
                    )
                {
                    texture.SaveAsPng(fileStream, texture.Width, texture.Height);
                    fileStream.Close();
                }
            }
        }

I need to save large amount of textures and i have huge memory leak. On windows phone 8 devices all works fine, this issue only on windows phone 7.


回答1:


Texture2D.SaveAsPng() has a known memory leak. I noticed this issue quite a while back and found a solution for it. The only solution is to create your own texture saving routine.

public static void Save(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);
    }
}

Which you can then call as (provided you keep it as an extension method) texture.SaveAs(texture.Width, texture.Height, ImageFormat.Png, fileName);




回答2:


Solved problem by getting texture data in byte array and saving it to Isolated Storage.

public static void SaveTextureToISF(string fileName, Texture2D texture)
{
    byte[] textureData = new byte[4 * texture.Width * texture.Height];
    texture.GetData(textureData);
    Save(fileName, textureData); //saving array to IS
}

And when texture is needed, load byte array from storage and load this data to new texture.

 public static Texture2D LoadTextureFromISF(string fileName, int width, int height)
 {
     Texture2D texture = new Texture2D(GraphicsDevice, width, height);
     byte[] textureData = Load(fileName); //load array from IS
     texture.SetData(textureData);
     return texture;
 }

One thing to note, when loading texture from storage you should know exactly dimension of saved texture and pass it as parameters in load function. This can be easily modified, but I don't need to.



来源:https://stackoverflow.com/questions/19248018/texture2d-saveaspng-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!