Reputation: 5597
I'm doing some resource management code where I take a bunch of different resources (image positions etc.) along with the actual images and make a single binary file out of them. Now, how do I actually include the .PNG file in a binary file and how do I read it back again? I would like to retain the .PNG compression.
I use BinaryWriter to write the data into a file, and BinaryReader to read it back. Here's an example of the format I'm using:
BinaryWriter writer = new BinaryWriter(new FileStream("file.tmp"));
writer.Write(name);
writer.Write(positionX);
writer.Write(positionY);
// Here should be the binary data of the PNG image
writer.Close();
BinaryReader reader = new BinaryReader(new FileStream("file.tmp"));
string name = reader.ReadString();
float posX = reader.ReadSingle();
float posY = reader.ReadSingle();
Bitmap bitmap = ... // Here I'd like to get the PNG data
reader.Close();
There is some other data too, both before and after the PNG data. Basically I will merge multiple of PNG files into this one binary file.
Upvotes: 0
Views: 2611
Reputation: 6203
Basically Paul Farry's answer is what you need to do. Read up on binary formats like the PNG format (see file header, chunks), the ZIP format (file headers, data descriptor), which implement something -- on a more elaborate level than you need -- the mechanism of storing different chunks of data in one file.
Upvotes: 0
Reputation: 4768
You will need to use so sort of Prefix (int) Followed by a Length Indicator (int) followed by your Payload (variable length) or if you know this will be the last thing in your file, then you can skip the prefix/size and just read until end of stream.
Then when you save your various parts, you write your prefix, then your length and then your data.
Ideally you could use some of the serialisers like protobuf to do a lot of the serialising for you, then you can just load your class back. I do this in one of my projects for Plugin Installers. The final File is a Zip, but the structures to generate the file "filenames, description, actual file locations, etc" are stored in a custom file like what you are describing.
if you are doing this all in memory then you could Serialise your PNG Image to a MemoryStream (get the size), then write the Size to the FileStream (file.tmp) followed by the MemorySteam Buffer
using (MemoryStream ms = new MemoryStream())
{
bitmap.Save(ms);
writer.Write(ms.Length);
ms.Position = 0;
ms.CopyTo(writer.BaseStream);
}
Upvotes: 2