WebP格式,谷歌(google)开发的一种旨在加快图片加载速度的图片格式。图片压缩体积大约只有JPEG的2/3,并能节省大量的服务器宽带资源和数据空间。WebP既支持有损压缩也支持无损压缩。相较编码JPEG文件,编码同样质量的WebP文件需要占用更少的计算资源. 可以使用Chrome打开WebP格式。
下载地址:
https://storage.googleapis.com/downloads.webmproject.org/releases/webp/index.html(不需要梯子)
下载下来之后可以通过查看README来看指令如何使用, 这里主要用到img2webp.
example: img2webp -loop 2 in0.png -lossy in1.jpg -d 80 in2.tiff -o out.webp
-loop: 循环次数
-lossless/-lossy: 无损压缩/有损压缩 默认是无损压缩
-o: 输出文件格式
-d: 帧持续时间 默认100毫秒, 一定要放在图片的前面才会生效
-q: 质量0-100,越高越好,越高生产文件也越大
shell脚本: towebp.sh
#!/bin/bash
path=$1
if [ ! $path ]; then
path='.'
fi
cd $path
filelist=$(ls .)
imgs=''
echo $filelist
for file in $filelist; do
#如果是文件且后缀名为png
if [ -f $file ] && [ "${file##*.}" = "png" ]; then
imgs=$imgs$file" "
fi
done
echo $imgs
img2webp -d 50 -lossy $imgs -o $path"/"out.webp
执行sh towebp.sh ~/xxx/xxx/imgs 后面的路径填写绝对路径,如果已经在是要打包的资源目录则可以不传, 最后会在你图片资源目录下生成一个out.webp的文件, 可有用浏览器打开进行预览.
android源码其实已经提供了支持, 只是还没有开放出来! 源码位置位于:
/frameworks/ex/framesequence
需要用到libframesequence.so和FrameSequence.java,FrameSequenceDrawable.java
View drawableView = findViewById(R.id.drawableview);
InputStream is = getResources().openRawResource(mResourceId);
FrameSequence fs = FrameSequence.decodeStream(is);
mDrawable = new FrameSequenceDrawable(fs, mProvider);
mDrawable.setOnFinishedListener(new FrameSequenceDrawable.OnFinishedListener() {
@Override
public void onFinished(FrameSequenceDrawable drawable) {
Toast.makeText(getApplicationContext(),
"The animation has finished", Toast.LENGTH_SHORT).show();
}
});
drawableView.setBackgroundDrawable(mDrawable);
我们主要用到的是FrameSequenceDrawable这个类, 这个类继承了Drawable, 构造函数中需要传如webp文件的InputStream, 通过so库去解析webp资源拿到图片的宽高,总的帧数等信息, 这里还初始化2张bitmap, 一张是当前要显示的那一帧, 另一张是下一张要显示的那一帧, 最后还初始化一个异步的handle, 执行start的时候会发送handle执行一个异步任务, FrameSequenceState的getFrame(int frameNr, Bitmap output, int previousFrameNr), frameNr是即将要显示的这一帧index, output是需要绘制的bitmap, previousFrameNr是前一帧的index, 该方法会返回这一帧的播放时间, 然后再调用Drawable的scheduleSelf方法, 传入上面计算好的时间, 时间到了之后就调用draw方法, 把bitmap显示到了ImageView上, 如果还有一帧则继续发handler走上面的过程.
这里需要注意的是, 系统默认系统的方案是实时去往bitmap上绘制绘制完之后就立马释放, 所以getFrame这个 方式是一个比较吃CPU的方法, 如果你帧率越高则cpu吃的越多, 你也可以将bitmap进行缓存, 直接从缓存中拿, 这样好处在不会暂用太多cpu但是会暂用内存, 所以大家可以折中一下, 根据当前设备情况做动态的调整.