如何将游戏元数据存储在.png文件中?

孢子允许玩家创build的生物被导出.png文件共享。 .png是生物的照片,但是如果它被导入到游戏中,生物的信息(如纹理,大小和形状)也会随之出现。

我怎样才能实现这样的function?

如果您真正需要的只是PNG文件,那么他们只是简单地将信息添加到文件中。 这实际上是一个隐写术的做法。 很多时候,这是用来隐藏有效载荷或秘密信息的东西看似公众所面临的。 但是,在这种情况下,这种方法可能就是所用的。 典型的Stegongraphy将隐藏内容的方式,但没有理由为什么不能简单地将数据附加到文件末尾的图像,并检索它。

几个工具为你编码这些数据,谷歌search至less可以提供这个和这个 。

PNG在开始时的字节签名$89 ,因此可能将信息插入到PNG结构本身之后,并简单地通过SPORE游戏进行parsing。

然而,由其他答案和谷歌search给出的进一步研究表明,孢子实际上只使用Stegongraphy版本来隐藏信息的阿尔法位。 考虑到这一点,我们可以排除附加数据或元数据的可能性。

应该指出的是, 元数据仍然是一个非常可行的select,如果数据正在本地parsing。 如果该信息可能在networking上共享或重新编码,则导出不保证保留所有信息。 使用像素数据时,可以毫无问题地继续无损转换。

PNG格式支持更多或更less的任意元数据。 PNG标准定义了一个PNG文件,基本上是一系列的块,其中一些是必需的(并包含图像数据)。 其他人则是可选的。 例如,存储用于存储伽玛信息或直方图数据的块。

特别是有一个tEXt块可以用来存储任意的键/值文本对。 这可以用来发送任何你想要的任意types的数据,只要你可以将这些数据表示为文本(这很可能)。

您将需要一个PNG库,允许您访问和操作这些额外的块(如参考库 ),或者您需要自己写一个。 那么这只是一个select如何编码你想要的数据作为键/值对的问题。 我会build议如下:

  • select以您的项目名称或代码名称为前缀的键名作为创build粗略的“名称空间”系统的一种方式,并避免与其他应用程序使用数据的潜在冲突
  • 不要尝试以这种方式存储实际纹理,请存储对游戏自己的资产数据库中指向的纹理的引用
  • 诸如生物或物体尺寸,重量等数据 – 简单的标量基本上 – 可以平均存储

为了得到更完整的答案,我还要指出还有另一种方法(以前由@Vaughn和@ Alexis的答案logging):直接在图像像素中编码所需的附加数据,将数据分布彩色通道的低位。 这种方法不需要使用额外的元数据,这意味着您可以完全实现它而不依赖于它,或者担心外部程序错误地处理元数据。 它也有一个非常高的“酷”因素,因为你只使用低位,图像仍然看起来是正确的人眼。 但是,这意味着您的图像大小是您可以存储的数据量的主要控制因素; 如果你需要更多的存储,你需要分配更多的像素到图像。

正如其他人所指出的,这个过程被称为隐写术 。

摩纳哥的开发人员实际上就他们和Spore是如何完成这件事作了精彩的文章 。

他们所做的基本总结很简单:

  • 将您的数据转换成二进制
  • 将目标图像转换为原始位图
  • 沿着图像的像素以一些可预测的模式走(它们只是从左上angular向左到右)。
  • 向每个像素的每个颜色通道的最低位写入一位
  • 再次将修改后的位图导出到png

只需做相反的事情来检索你的数据。

这个过程背后的基本思想是图像中有很多像素,每个颜色通道的最低位不会有很大的差别。 另外,你写的大约一半位就是图像中的位。 你回来的东西基本上是正确的形象,但奇怪的文物。 他需要时间注意,如果真正开始对比度/饱和度并放大,这些文物才会真正引人注意。尽pipe如此,他的源图像还是有很多初始噪点的。

从文章:

在最后的图像中注意噪音中几乎没有明显的水平线。 这是关卡数据的结尾。 这意味着我实际上可以将所有级别的数据适合265×120像素的图像,只使用最低有效位。

一个棘手的附录:

我可以做的事情,我相信孢子人也是这样做的,实际上是使用100%透明像素中的所有颜色位。 由于这些像素是透明的,因此设置它们的颜色并不重要。

我不能这样做,但是,因为我正在使用整个图像,这意味着我没有透明像素的工作。

为什么这个技术只是将其存储在元数据中?

  • 这很有趣! 🙂
  • 服务可能会破坏元数据(可能作为隐私/安全function),但不应该破坏你的PNG的像素,除非他们有积极的图像托pipe要求(看着你,脸书)。 但是,如果他们完全重新出口你的形象,没有什么可靠的做法。

额外的功劳:为了降低噪音的显着性,您可以使用固定种子的PRNG来select要修改的像素。 您也可以仅以类似的方式修改某些颜色通道。

我从Sporepedia下载并检查了一些孢子生物。 从那些我了解到的:

  • 除了标准图像数据之外,图像不包含任何信息。
  • 已经存储了速记数据而没有考虑图像,可以想象透明部分是专门使用的,但是它们不是。
  • 存储使用取决于需要存储的信息量,一些图像仅使用最低有效位来存储数据,一些使用了两个最低有效位,一些可能使用更多。
  • 孢子格式避免只在图像的一部分上使用一点,最低有效位在整个图像中变化,如果使用第二个最低有效位,它被用在整个图像上。 这大概是用随机填充完成的。 这样避免了质量的改变,而噪声本身可能会使观众感到更加不安。
  • 所有四个通道的使用方式相同,不透明通道没有特殊处理,因此一些透明像素略微不透明,而一些不透明像素稍微透明。

值得注意的是,这正是Spore所做的,这是一个在大多数其他问题之前将简单化的方法。

使用速记而不是附加数据块的select意味着,如果图像被重新编码(例如通过网站),则数据将存活,尽pipe它不能经受缩放或Jpeg压缩。

我认为最显着的select是实际上只对图像中的一个id进行编码,并将实际的数据存储在一个中央服务器上,这个id可以被交换成确切的生物数据。 这样一个id将会足够短,以至于它可以以缩放和压缩容忍速度格式进行编码。

对孢子格式的简单改进可能包括:

  • 只使用或偏好使用透明像素的颜色值,它们不会造成视觉差异。
  • 多使用蓝色通道,绿色通道less,蓝色对图像的感知影响较小。
  • 保持每个像素的亮度接近于不变并且将数据编码为色度,这个参数中的一些噪声实际上是人类无法察觉的。