Сериализация растрового изображения в C # /. NET в XML - PullRequest
17 голосов
/ 15 декабря 2009

Я хочу 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; }

Теперь я обнаружил, что сериализация растрового изображения с XML-сериализатором по умолчанию не работает, поскольку у него нет общедоступного конструктора без параметров, что является обязательным для сериализатора xml по умолчанию.

Мне известно следующее:

  • Существует обходной путь, размещенный здесь: http://www.dotnetspider.com/resources/4759-XML-Serialization-C-Part-II-Images.aspx , Однако, поскольку это включает в себя добавление еще одного свойства, это кажется мне хаком.
  • На sourceforge существует также проект по глубокой сериализации XML.

Я бы предпочел не ссылаться на другой проект и не настраивать мой класс, чтобы разрешить сериализацию этих растровых изображений в формате xml.

Нет ли способа сохранить это простым?

Большое спасибо, Марсель

Ответы [ 4 ]

42 голосов
/ 15 декабря 2009

Я бы сделал что-то вроде:

[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);
            }
        }
    }
}
5 голосов
/ 15 декабря 2009

Вы также можете реализовать ISerializable и использовать SerializationInfo для ручной обработки вашего растрового содержимого.

РЕДАКТИРОВАТЬ: Жуан прав: правильный способ работы с сериализацией 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();
        }
    }
}
2 голосов
/ 15 декабря 2009

Реализуйте 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; }
}
2 голосов
/ 15 декабря 2009

Класс BitMap не был разработан для легкой XML-сериализации. Поэтому нет простого способа исправить проектное решение.

...