2010-08-28 3 views
2

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

Я реализовал нижеследующее решение, но проблема в том, что согласно 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(); 

    } 



} 
+0

Примечание другая линия в связанной документации, которая говорит: * Вы должны держите поток открытым на всю жизнь изображения. * – EMP

ответ

9

Метод 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); 
    } 
} 
+0

Спасибо за это элегантное решение :-) –

1

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

0

Идея вне-стен, которые могли бы работы (я определенно не проверял это):

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

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

0

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