0

我正在做一些资源管理代码,其中我将一堆不同的资源(图像位置等)与实际图像一起使用,并用它们制作一个二进制文件。现在,我如何实际将 .PNG 文件包含在二进制文件中,以及如何再次读回它?我想保留 .PNG 压缩。

我使用 BinaryWriter 将数据写入文件,并使用 BinaryReader 将其读回。这是我正在使用的格式的示例:

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();

PNG数据之前和之后还有一些其他数据。基本上我会将多个 PNG 文件合并到这个二进制文件中。

4

2 回答 2

2

您将需要使用这种前缀(int),后跟长度指示符(int),然后是您的有效负载(可变长度),或者如果您知道这将是文件中的最后一件事,那么您可以跳过前缀/大小并阅读直到流结束。

然后当你保存你的各个部分时,你写你的前缀,然后是你的长度,然后是你的数据。

理想情况下,您可以使用一些像 protobuf 这样的序列化程序来为您进行大量序列化,然后您就可以重新加载您的类。我在我的插件安装程序项目之一中执行此操作。最终文件是 Zip,但生成文件“文件名、描述、实际文件位置等”的结构存储在自定义文件中,就像您所描述的那样。

如果您在内存中执行此操作,那么您可以将 PNG 图像序列化为 MemoryStream(获取大小),然后将大小写入 FileStream(file.tmp),然后写入 MemorySteam 缓冲区

using (MemoryStream ms = new MemoryStream())
{
    bitmap.Save(ms);

    writer.Write(ms.Length);
    ms.Position = 0;
    ms.CopyTo(writer.BaseStream);
}
于 2013-05-31T05:10:01.527 回答
0

基本上保罗法里的回答是你需要做的。阅读二进制格式,如PNG 格式(参见文件头、块)、ZIP 格式(文件头、数据描述符),它们实现了一些东西——比你需要的更复杂——存储不同块的机制数据在一个文件中。

于 2013-05-31T06:04:48.293 回答