Android 如何实现webp转png?看这篇就够了

Webp是什么, 请移步 What‘s Webp?

由于webp与生俱有优点,webp如今使用已经很广泛了,包括客户端。比如今日头条客户端页面的图片都是webp格式的。客户端碰到与webp有关的一些问题,大概有:

  • webp图片的显示
  • webp转成其他格式图片
  • 其他格式图片转成webp

比如我们有一个这样的需求:

客户端将webp格式的图片转成png后上传到服务端(由于服务端暂时还不支持webp图片的上传)

如何将webp转成png?我们需要依赖Google的webp源码的支持,但是webp的源码都是用C来实现的,需要将它编译成.so库,同时还需要提供几个供Java层调用的API,用于实现webp与png相互转换。在这里我们参考开源项目webp-android-backport

webp-android-backport

下面详细说说如何编译出我们想要的.so库

1. 将webp-android-backport项目源码下载至本地后用AS打开

2. webp源码下载

因为这个开源项目对于webp的源码依赖方式是通过git submodule来管理的,如果没有Google 开发者账号不方便下载。
还可以通过下面的链接获取源码


3. 编译

下载源码后放置到工程目录/jni,进行编译,如图


认真看了开源项目源码后发现,这样编译出来的aar库其实是有bug的,尴尬😓

image.png

为了解决该bug,我们需要将接口类中私有API定义成public,方便上层使用。这里的修改涉及到jni的编译了,期间我也碰到了一些比较坑的问题。(这里我会用另一篇博客来详细说明)
在编译so库的时候,可以修改webp-android-backport-library包下面的Application.mk文件中APP_ABI 参数,来指定项目需要支持的cpu架构平台。

#APP_ABI := armeabi-v7a x86 armeabi
#APP_ABI := armeabi
APP_ABI := armeabi-v7a
APP_CPPFLAGS := -fno-rtti -fno-exceptions
APP_PLATFORM := android-8

ifndef WEBP_BACKPORT_DEBUG_NATIVE
# Force release compilation in release optimizations, even if application is debuggable by manifest
APP_OPTIM := release
endif

编译完成会在webp-android-backport-library/build/outputs目录下生成一个aar文件,这样我们就完成了webp库的编译了。

如何使用编译生成的库来实现webp转png呢?

上代码:

/**
 * author : J.Chou
 * e-mail : who_know_me@163.com
 * time   : 2018/08/13 10:53 PM
 * version: 1.0
 * description:
 */
public class Webp2PngUtil {

  public static boolean isWebpImage(File imageFile) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
    String type = options.outMimeType;
    return type.equals("image/webp");
  }

  public static Bitmap webp2Bitmap(String path) {
    Bitmap bitmap = null;
    try {
      bitmap = WebPFactory.nativeDecodeFile(path, null);
    } catch (Throwable t) {
      t.printStackTrace();
    }
    return bitmap;
  }

  @SuppressWarnings("ResultOfMethodCallIgnored")
  public static String bitmap2Png(Bitmap bitmap) {
    if(bitmap == null) return null;
    String pngImagePath = null;
    File pngFile = new File(FileUtil.getCacheDir() + File.separator + "webp2png" + System.currentTimeMillis() + ".png");
    if(pngFile.exists()){
      pngFile.delete();
    }
    FileOutputStream out;
    try{
      out = new FileOutputStream(pngFile);
      if(bitmap.compress(Bitmap.CompressFormat.PNG, 90, out)) {
        out.flush();
        out.close();
      }
      pngImagePath = pngFile.getAbsolutePath();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }catch (IOException e) {
      e.printStackTrace();
    }
    return pngImagePath;
  }
}

这个工具类使用到aar库中的接口类WebPFactory.
这里简单说一下上传图片的逻辑
先判断上传文件(webpFile)是否是webp格式(不能判断图片后缀名),如果是,则将该文件转成png图片文件(webpFile ---> pngFile),然后将pngFile上传到服务端。

使用工具类Webp2PngUtil来实现webp转png的实例代码

 if (Webp2PngUtil.isWebpImage(new File(originalImagePath))) {
    String pngImagePath = Webp2PngUtil.bitmap2Png(Webp2PngUtil.webp2Bitmap(originalImagePath));
    if (!TextUtils.isEmpty(pngImagePath)) {
      originalImagePath = pngImagePath;
    }
  }

实现这样的需求还是比较容易,主要的精力可以会消耗在aar库的编译上。
由于aar中包含了webp的so库,而且这个so库其实不小(随着webp的源码越来越多,编译后的so库也在不断的增大),考虑到APP包的size,支持的cpu架构也不能太多。

极好的参考资料
1. http://www.geekince.com/android/2017/07/31/android-webp-build/
2. http://www.hahack.com/wiki/sundries-webp.html
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,445评论 25 707
  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_x阅读 15,967评论 3 119
  • 有些时候心情不好就想一个人待会,然后反省自己,想通了就好了。有时候就什么都不想,打打篮球,洗一堆衣服,收拾好床,用...
    菠萝凤梨黑凤梨阅读 92评论 0 0
  • 1 你买了新裤子兴冲冲打电话让我看看。一上车你就迫不及待展示。“怎么买条这颜色的裤子,可惜了这两条大长腿,让人不忍...
    流失的青春阅读 968评论 45 57
  • 记得以前台湾学生来上海交流的时候,我们在聊天时会来对比下两地语言、文字、生活方式等的不同或是我们共同的兴趣,如台剧...
    大河小河与一条魚的传奇阅读 357评论 0 0