C#:将多个图像保存到单个文件中

时间:2010-08-28 10:06:15

标签: c# image stream

我正在开发一个维护图像字典的类。 此字典应保存到文件并从文件加载。

我实现了以下解决方案,但问题是根据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 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分:1)

您可以尝试使用BinaryFormatter将字典dict序列化/反序列化到文件中。

答案 2 :(得分:0)

可能工作的一种彻头彻尾的想法(我绝对没有对此进行过测试):

  • 创建一个Substream类,该类派生自Stream并包装基础Stream。它的构造函数会将Streamoffset放入Substream视为零的流中。 Substream基本上是一个受约束的视图或窗口到另一个流(在这种情况下,你的文件流)。
  • 最初,在Substream上创建FileStreamoffset为零。
  • 当您致电Image.FromStream时,Substream的位置会前进到某个新位置(请拨打p)。
  • 使用Substream FileStreamoffset创建一个新的p
  • 循环直到完成。

我的想法是,即使Image.FromStream重置基础流,它也会将Substream重置为FileStream的某个偏移量,这正是您真正想要的。

答案 3 :(得分:0)

为什么不为该文件创建自定义标题,包括(图像数量,实际图像的起始地址以及每个图像之间的行分隔符)