问题
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