У меня есть класс Texture
, который содержит System.Drawing.Bitmap Bitmap
и некоторые дополнительные данные и методы. Я хочу, чтобы сериализации-десериализации его в двоичный файл, так что я реализую ISerializable
интерфейсу так:Как правильно сериализовать растровое изображение в C#?
public Texture(SerializationInfo info, StreamingContext context)
{
PixelFormat pixelFormat = (PixelFormat)info.GetInt32("PixelFormat");
int width = info.GetInt32("Width");
int height = info.GetInt32("Height");
int stride = info.GetInt32("Stride");
byte[] raw = (byte[])info.GetValue("Raw", typeof(byte[]));
IntPtr unmanagedPointer = Marshal.AllocHGlobal(raw.Length);
Marshal.Copy(raw, 0, unmanagedPointer, raw.Length);
Bitmap = new Bitmap(width, height, stride, pixelFormat, unmanagedPointer);
Marshal.FreeHGlobal(unmanagedPointer);
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("PixelFormat", (int)Bitmap.PixelFormat);
info.AddValue("Width", Bitmap.Width);
info.AddValue("Height", Bitmap.Height);
BitmapData data = Bitmap.LockBits(new Rectangle(0, 0, Bitmap.Width, Bitmap.Height), ImageLockMode.ReadOnly, Bitmap.PixelFormat);
info.AddValue("Stride", data.Stride);
byte[] raw = new byte[data.Height * Math.Abs(data.Stride)];
Marshal.Copy(data.Scan0, raw, 0, raw.Length);
info.AddValue("Raw", raw);
Bitmap.UnlockBits(data);
}
Но после сериализации и deserealization Bitmap
выглядит испорченный. Что я сделал не так? Как это сделать правильно?
Вы не можете позвонить Marshal.FreeHGlobal() до * после * растровое расположен. Да, это очень больно. Вместо того, чтобы помогать так много, подумайте об использовании Image.Save() для сохранения в MemoryStream и сериализации байтов. Загрузите его снова с помощью MemoryStream, не удаляйте его. –