Joel
Joel

Reputation: 1630

C# storing multiple images in a file

I am working on a map save file. Essentially this map save is going to contain information such as the location of entities, as well as the images of each of the chunks in this world (which change during gameplay). I could save this all in multiple files, however i would rather keep it as one file for simplicity sake (simple for the user that is...) and also, because i do not want the maps to be editable (not just by double clicking an image file at least).

So essentially, it comes down to writing to a file, currently i have it all working, i am writing 2 bytes to indicate the number of chunks along the x and y axis of the world, then go through and store a byte for alpha, red, green and blue for each pixel of each chunk.

Each chunk is a 512 by 512 image. When i save a world (only containing the chunks and world size (2 bytes). The file size is as expected. number of chunks * 512 * 512 * 4 (ARGB) + 2 (world size) bytes.

However, looking at the file size of images of each chunk which i just did a test export of with Bitmap.Save(), each of those image files have a size of 10 - 20 KB. basically, a lot less.

So I need to somehow store multiple images in a single file, taking up a more realistic amount of space.

Either, somehow getting what Bitmap.Save() would usually export, and adding that into the file or having a more space-saving way of storing the image manually, than 4 bytes a pixel.

Does anyone know an approach to either of those? Or another idea to store multiple images effectively?

Upvotes: 1

Views: 3175

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038800

How about using a BinaryFormatter?

So design a class to represent your model data that you want to store:

[Serializable]
public class MyModel
{
    public byte[][] Images { get; set; }
}

and then assuming you have an instance of this class:

var model = new MyModel
{
    Images = new[]
    {
        File.ReadAllBytes(@"d:\work\image1.png"),
        File.ReadAllBytes(@"d:\work\image2.png"),
        File.ReadAllBytes(@"d:\work\image3.png"),
    }
};

you could serialize it to a file:

var formatter = new BinaryFormatter();
using (var output = File.Create("images.dat"))
{
    formatter.Serialize(output, model);
}

Of course if you have an instance of a Bitmap, it's just a matter of converting it to the corresponding byte array in order to stuff it inside the model.

And then later when you want to read the data back:

using (var input = File.OpenRead("images.dat"))
{
    var model = (MyModel)formatter.Deserialize(input);
}

Your model could of course be as complex as you wish. You could associate metadata to those images such as their name, type, ... by designing yet another model.

Upvotes: 8

Related Questions