21 February 2019

动机

网络游戏所有资源都是从网络加载的,需要压缩资源。因为你不知道用户用的网络带宽是多少,体积越大的游戏,进入游戏的等待时间越慢。而且微信小游戏对游戏体积也有限制。所以能把资源压缩到最小,对游戏的数据有很大帮助。 而图片资源是所有游戏资源中最大的。把游戏中的图片资源压缩是最重要的。

格式对比

腊鸭默认的格式是png,jpg。jpg因为是有损压缩格式,体积还可以接受。但是png的体积就非常大了。

目前可选的其它图片格式

png8

默认的png每个像素32位的,png8每个像素只有8位。这个格式能有效的减少体积。而且不用写过多代码,但是精度有点低。渐变色的时候能明显感受出质量下降。

gif

质量更不好

bpg

基于视频压缩的格式。体积最小,质量最好。但是没有浏览器默认支持这个格式。

webp

体积很小,质量不错。谷歌浏览器,安卓系统,ios12,基于谷歌内核的edge浏览器,支持这个格式。只有一些ios系统,和ie,老edge不支持这个格式。

把格式压缩成这种格式是最佳选择。

实现

http://libwebpjs.appspot.com/v0.6.0/

通过代码判断是否支持webp

var canvas:Object = Browser.window.document.createElement('canvas');
canvas.width = 2;
canvas.height = 2;
canvas.style.width = 2 + "px";
canvas.style.height = 2 + "px";
var isSupport = !![].map && canvas.toDataURL('image/webp').indexOf('data:image/webp') == 0;		

如果支持这个格式就用原生的渲染,如果不支持用 libwebp-0.6.0.min.js 软件解码

需要改动几个类

Texture2d;WebglImage

最终效果

测试demo

2020.3.16更新

考虑到 https://libwebpjs.appspot.com/ 这个库糟糕的性能,以后可以尝试用谷歌官方的js库,考虑wasm

https://github.com/webmproject/libwebp/tree/master/webp_js

编译谷歌版的webpjs

首先谷歌那个大sb,根本不提供可运行的js程序。需要自己通过源码编译。然后文档还是错的,所以开启了痛苦的编译c++之旅

  • 先下载 https://github.com/webmproject/libwebp 这个库。
  • 再安装 https://emscripten.org/docs/getting_started/Tutorial.html
  • 下载 https://github.com/emscripten-core/emsdk
  • 命令行进入emsdk emsdk install latest
  • 命令行进入libwebp/webp_js 把 D:\sdk\emsdk-master\emsdk_env.bat 拖到命令行窗口。执行 cmake -DWEBP_BUILD_WEBP_JS=ON -DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=1 -DCMAKE_TOOLCHAIN_FILE=D:/sdk/emsdk-master/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake ..
  • 用vs打开allbuild开始编译。编译的过程中会报2种错误,第一个就是找不到xxx.o,然后去报错目录会发现,存在xxx.obj,不存在xxx.o。所以把所有xxx.obj改成xxx.o.
  • 然后最终卡在找不到sdl.h了。发现了另一个编译好的版本 https://github.com/webmproject/libwebp-demo/tree/gh-pages/webp_wasm

测试结果

直接看例子吧,效果还是不错的。谷歌的js比webpjs效率大约提升一倍。wasm提升4倍。但是发现这个版本的aswm有内存限制。2048的图会报错。看来要还是要自己编译源代码解除这个限制

wasm测试demo

微信小程序

https://www.infoq.cn/article/Mqt8oOtSwDW-Wf0iQBji