C #: сохранить несколько изображений в один файл - PullRequest
2 голосов
/ 28 августа 2010

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

Я реализовал приведенное ниже решение, но проблема в том, что согласно MSDN документация для Image.FromStream ();
http://msdn.microsoft.com/en-us/library/93z9ee4x(v=VS.80).aspx

«Поток сбрасывается в ноль, если этот метод вызывается последовательно с одним и тем же потоком.»

Есть идеи как это исправить? Скорость загрузки словаря критична.

class ImageDictionary
{
    private Dictionary<string, Image> dict = new Dictionary<string, Image>();

    public void AddImage(string resourceName, string filename)
    {
       //...
    }

    public Image GetImage(string resourceName) 
    {
       //...
    }


    public void Save(string filename)
    {
        var stream = new FileStream(filename, FileMode.Create);
        var writer = new BinaryWriter(stream);
        writer.Write((Int32) dict.Count);
        foreach (string key in dict.Keys)
        {
            writer.Write(key);

            Image img;
            dict.TryGetValue(key, out img);
            img.Save(stream,System.Drawing.Imaging.ImageFormat.Png);
        }
        writer.Close();
        stream.Close();
    }

    public void Load(string filename)
    {
        var stream = new FileStream(filename, FileMode.Open);
        var reader = new BinaryReader(stream);
        Int32 count = reader.ReadInt32();
        dict.Clear();

        for (int i = 0; i < count; i++)
        {
            string key = reader.ReadString();
            Image img = Image.FromStream(stream);
            dict.Add(key, img);

        }

        reader.Close();
        stream.Close();

    }



}

Ответы [ 4 ]

9 голосов
/ 28 августа 2010

Метод Image.FromStream ожидает допустимый поток изображений. Вы объединяете несколько изображений в один файл, и если вы хотите восстановить их, вам также необходимо сохранить их размер в дополнение к их количеству. Более простым решением было бы просто сериализовать словарь изображений в двоичном виде:

public void Save(string filename)
{
    var serializer = new BinaryFormatter();
    using (var stream = File.Create(filename))
    {
        serializer.Serialize(stream, dict);
    }
}

public void Load(string filename)
{
    var serializer = new BinaryFormatter();
    using (var stream = File.Open(filename, FileMode.Open))
    {
        dict = (Dictionary<string, Image>)serializer.Deserialize(stream);
    }
}
1 голос
/ 28 августа 2010

Вы можете попробовать использовать BinaryFormatter для сериализации / десериализации вашего словаря dict в / из файла.

0 голосов
/ 28 августа 2010

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

0 голосов
/ 28 августа 2010

Идея о том, что может работать (я определенно не проверял это):

  • Создайте Substream класс, производный от Stream, а также обертывающий базовый Stream. Его конструктор будет принимать Stream и offset в этом потоке, который Substream рассматривает как ноль. Substream - это, по сути, ограниченное представление или окно в другой поток (в данном случае, ваш файловый поток).
  • Сначала создайте Substream поверх FileStream с offset, равным нулю.
  • Когда вы звоните Image.FromStream, позиция вашего Substream переместится на какую-то новую позицию (назовите это p).
  • Создайте новый Substream поверх вашего FileStream с offset из p.
  • Цикл до конца.

Идея состоит в том, что даже если Image.FromStream сбрасывает базовый поток, он сбросит Substream к некоторому смещению в FileStream, что вам действительно нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...