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();
}
}
4 ответа
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);
}
}
Вы можете попробовать использовать BinaryFormatter для сериализации / десериализации вашего словаря. dict
в / из файла.
Почему бы не создать пользовательский заголовок для этого файла, который включает в себя (количество изображений, начальный адрес реальных изображений и сделать между каждым изображением разделитель строк)
Идея вне стен, которая может работать (я определенно не проверял это):
- Создать
Substream
класс, который происходит отStream
а также оборачивает основнуюStream
, Его конструктор будет приниматьStream
иoffset
в этот поток, чтоSubstream
трактует как ноль.Substream
это в основном ограниченное представление или окно в другой поток (в данном случае, ваш файловый поток). - Изначально создайте
Substream
над вашимFileStream
сoffset
нуля. - Когда вы звоните
Image.FromStream
, положение вашегоSubstream
будет продвигаться к какой-то новой позиции (позвонитеp
). - Создать новый
Substream
над вашимFileStream
сoffset
изp
, - Цикл до конца.
Идея в том, что даже если Image.FromStream
сбрасывает основной поток, он сбрасывает Substream
в некотором смещении в FileStream
, что вы действительно хотите.