Reputation: 145
I am working on a class that maintains a dictionary of images. This dictionary should be saved to and loaded from a file.
I implemented the below solution, but the problem is that according to MSDN
documentation for Image.FromStream();
http://msdn.microsoft.com/en-us/library/93z9ee4x(v=VS.80).aspx
"The stream is reset to zero if this method is called successively with the same stream."
Any ideas how to fix this? The speed of loading the dictionary is critical.
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();
}
}
Upvotes: 1
Views: 5746
Reputation: 6729
why not create custom header for that file which includes (number of images,starting address of the actual images and make between each image a line separator)
Upvotes: 0
Reputation: 29476
An off-the-wall idea that might work (I have definitely not tested this):
Substream
class that derives from Stream
and also wraps an underlying Stream
. Its constructor would take a Stream
and an offset
into that stream that the Substream
treats as zero. Substream
is basically a constrained view or window into another stream (in this case, your file stream).Substream
over your FileStream
with an offset
of zero.Image.FromStream
, the position of your Substream
will advance to some new position (call this p
).Substream
over your FileStream
with an offset
of p
.The idea is that even if Image.FromStream
resets the underlying stream, it will reset the Substream
to some offset into the FileStream
, which is what you really want.
Upvotes: 0
Reputation: 1038820
The Image.FromStream
method expects a valid image stream. You are concatenating multiple images into a single file and if you want to reconstruct them you will also need to save their size in addition to their number. An easier solution would be to simply binary serialize the image dictionary:
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);
}
}
Upvotes: 8
Reputation: 6628
You can try to use BinaryFormatter to serialize/deserialize your dictionary dict
to/from file.
Upvotes: 1