Подтвердить что ты не робот

Сериализация растрового изображения в С#/.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 по умолчанию.

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

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

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

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

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

4b9b3361

Ответ 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; }
}