图片读取与转换

游戏制作中有时需要读取图片像素,本文记录在运行时直接读取图片像素,与在引擎外预处理并转换为其他数据格式之间的性能与资源取舍。

优化资源管理引擎开发
2026/1/4

直接加载图片

  游戏引擎基本上都提供了图片解析的方法,使用引擎自带的图片解析方法也可以拿到图片的数据。 我这里认为这个方式的最大的优点就是放一张图进去就行了,由代码内部进行处理,完全不需要工具链,能够直观的看见预期效果简化了流程。 缺点是运行的时候把压力全部放在了CPU侧,图片越大内存占用越大,内存占用大致为 宽*高*4byte 分辨率增大时按面积增长。 由于是内部加载,极可能出现了解析完成过后数据不释放造成内存泄漏。
这种方法还是比较适合快速原型开发

可读数据格式

Json

  JSON是常见的文本数据格式,可读性好,但在体积和解析效率上并不占优。
测试图片这是一个20*20像素的图片,大小为661Byte。在转换为Json并保留想要的格式后格式如下

{
  "width": 20,
  "height": 20,
  "colorCount": 6,
  "pixels": [
    3,3,3,3,10,10,5,5,3,3,3,3,5,5,10,10,3,3,3,3,
    3,3,3,10,8,5,8,10,3,3,3,3,10,8,5,8,10,3,3,3,
    3,3,3,10,8,5,5,8,10,10,10,10,8,5,5,8,10,3,3,3,
    3,3,10,8,10,10,10,10,8,8,8,8,10,10,10,10,8,10,3,3,
    3,3,10,8,5,5,5,5,8,8,8,8,5,5,5,5,8,10,3,3,
    3,3,10,8,5,5,2,2,8,8,8,8,2,2,5,5,8,10,3,3,
    3,3,10,8,5,2,2,2,2,8,8,2,2,2,2,5,8,10,3,3,
    3,3,10,8,2,12,12,2,2,5,5,2,2,12,12,2,8,10,3,3,
    3,10,10,8,2,12,12,12,2,2,2,2,12,12,12,2,8,10,10,3,
    3,10,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,8,10,3,
    10,8,2,2,2,2,2,2,12,12,12,12,2,2,2,2,2,2,8,10,
    10,8,2,2,2,2,2,2,12,12,12,12,2,2,2,2,2,2,8,10,
    10,8,2,2,2,12,2,2,2,12,12,2,2,2,12,2,2,2,8,10,
    5,10,2,2,2,2,12,12,12,12,12,12,12,12,2,2,2,2,10,5,
    5,10,2,2,2,2,2,2,12,12,12,12,2,2,2,2,2,2,10,5,
    3,3,10,2,2,2,2,2,2,12,12,2,2,2,2,2,2,10,3,3,
    3,3,3,10,2,2,2,2,2,2,2,2,2,2,2,2,10,3,3,3,
    3,3,3,3,10,10,10,2,2,2,2,2,2,10,10,10,3,3,3,3,
    3,3,3,3,5,5,5,10,10,10,10,10,10,5,5,5,3,3,3,3
  ]
}

即使将数据压缩成一行大小也有910Byte,体积增大会带来更多 IO 成本,且实际运行的时候仍然要 JSON.parse 构建对象和数据结构,从而产生更多的分配与GC压力,总体上也未必能“换到性能”。

优点缺点
可读性强体积大
结构清晰解析需要字符串处理,性能较低

Json还是更适合结构化、规模较小、低频读取的数据(如玩家存档、配置表、调试数据等)。

Bin

  二进制文件在运行时场景下几乎可以认为是最合适的数据形式,运行时几乎无解析成本,GC压力低,对比其他数据文件体积小无冗余。
  同时缺点也很明显,工具链不完善使用起来非常的痛苦。在没有完善配套工具的情况下只能看见最终运行结果,一旦结果错误那么只能靠工具反解析,提高了问题定位的成本。
  在写这篇文章的时候做的项目是一个休闲小游戏主要使用的是像素图。这里引入 RLE 压缩: RLE(Run-Length Encoding,游程长度编码)是一种简单的无损数据压缩算法,实现很简单就是把连续相同的数据放在一起。 非常适合连续且重复的数据,像素图就非常的合适。

引用

封面图片:Ocean Background
作者:KnoblePersona
来源:OpenGameArt.org
许可协议:Creative Commons Attribution 3.0 (CC-BY 3.0)