Сериализация растрового изображения в С#/.NET для XML
Я хочу XML-Serialize сложный тип (класс), который имеет свойство типа System.Drawing.Bitmap.
/// <summary>
/// Gets or sets the large icon, a 32x32 pixel image representing this face.
/// </summary>
/// <value>The large icon.</value>
public Bitmap LargeIcon { get; set; }
Теперь я выяснил, что сериализация Bitmap с помощью стандартного XML-сериализатора не работает, потому что у него нет открытого конструктора без параметров, который является обязательным для сериализатора xml по умолчанию.
Мне известно следующее:
Я бы предпочел не ссылаться на другой проект и не просто настраивать мой класс, чтобы просто разрешить сериализацию XML этих растровых изображений.
Нет ли способа сохранить это просто?
Большое спасибо, Marcel
Ответы
Ответ 1
Я бы сделал что-то вроде:
[XmlIgnore]
public Bitmap LargeIcon { get; set; }
[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)]
[XmlElement("LargeIcon")]
public byte[] LargeIconSerialized
{
get { // serialize
if (LargeIcon == null) return null;
using (MemoryStream ms = new MemoryStream()) {
LargeIcon.Save(ms, ImageFormat.Bmp);
return ms.ToArray();
}
}
set { // deserialize
if (value == null) {
LargeIcon = null;
} else {
using (MemoryStream ms = new MemoryStream(value)) {
LargeIcon = new Bitmap(ms);
}
}
}
}
Ответ 2
Вы также можете реализовать ISerializable
и использовать SerializationInfo
для ручного управления содержимым растрового изображения.
EDIT: João прав: Правильный способ обработки XML-сериализации состоит в реализации IXmlSerializable
, а не ISerializable
:
public class MyImage : IXmlSerializable
{
public string Name { get; set; }
public Bitmap Image { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public void ReadXml(System.Xml.XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("Name");
writer.WriteString(this.Name);
writer.WriteEndElement();
using(MemoryStream ms = new MemoryStream())
{
this.Image.Save(ms, ImageFormat.Bmp );
byte[] bitmapData = ms.ToArray();
writer.WriteStartElement("Image");
writer.WriteBase64(bitmapData, 0, bitmapData.Length);
writer.WriteEndElement();
}
}
}
Ответ 3
Класс BitMap не был разработан для простого XML-сериализации. Итак, нет, нет простого способа исправить дизайнерское решение.
Ответ 4
Внесите IXmlSerializable
, а затем вручную обработайте все данные о сериализации.
Поскольку вы говорите, что это большой тип, и у вас есть только проблема с растровым изображением, подумайте о том, чтобы сделать что-то вроде этого:
public class BitmapContainer : IXmlSerializable
{
public BitmapContainer() { }
public Bitmap Data { get; set; }
public XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public void WriteXml(XmlWriter writer)
{
throw new NotImplementedException();
}
}
public class TypeWithBitmap
{
public BitmapContainer MyImage { get; set; }
public string Name { get; set; }
}