zoukankan      html  css  js  c++  java
  • 转载- 支持Android4.0以下webp的使用

    原文地址:
     
    http://blog.csdn.net/jiwangkailai02/article/details/17015451
     

    支持Android4.0以下webp的使用

    分类: Android相关

    最近项目中需要使用到webp,主要目的是减少网络流量(同一张图片,webp格式能比jpg格式小约30%)。但是Android在4.0以上BitmapFactory才支持webp,今天的操作就是要使Android4.0以下的版本也能进行webp的解压缩。

    首先,需要搭建NDK开发的环境

    1.下载并安装Cygwin

    Cygwin下载地址:http://www.cygwin.com/

    按照向导一路向下,(使用默认的镜像路径http://www.mirrors.163.com/,这个貌似比较快)。

    到达这一步:

    选择Devel,点开。选择我们必须安装的5个组件:binutils ,gcc(包含core和g++) ,gcc-mingw(包含core和g++) ,gdb,make。(有的时候你需要更多的组件,根据自己需要再安装)

    选择完后,点击下一步,直到安装完成。

    运行cygwin,输入make -v 和 gcc -v 如果能显示版本,则表示安装成功。

    2.下载并配置NDK

    NDK下载地址:http://developer.android.com/tools/sdk/ndk/index.html

    NDK安装很简单,下载完成后把文件解压到指定的位置即可。

    NDK环境配置:

    修改Cygwin目录/home/<username> 下的.bash_profile文件,在文件末尾加入如下代码:

    ANDROID_NDK_ROOT=/cygdrive/解压后NDK文件的路径 /*(例如:/cygdrive/d/android-ndk-r9b)*/

    export ANDROID_NDK_ROOT

    至此,准备工作已经完毕。

    其次,我们需要下载并编辑webp的源文件

    我们使用最新的0.3.1版本的webp源文件,下载地址为:http://code.google.com/p/webp/downloads/detail?name=libwebp-0.3.1.tar.gz&can=2&q=

    下载完成后,解压缩,提出Android.mk文件、src文件夹和swig文件下的libwebp.jar文件和libwebp_java_wrap.c文件。并将libwebp_java_wrap.c文件移动到src文件夹下。

    在工程目录下新建名字为jni的文件夹。然后将Android.mk文件、src文件夹移动到jni文件夹下。最后,将libwebp.jar引入到工程中。

    编辑Android.mk文件夹,在include $(CLEAR_VARS)
    LOCAL_SRC_FILES := 中添加:src/libwebp_java_wrap.c

    并将include $(BUILD_STATIC_LIBRARY)该为include $(BUILD_SHARED_LIBRARY)

    如下:

    (BUILD_STATIC_LIBRARY和BUILD-SHARED_LIBRARY的区别参考:http://stackoverflow.com/questions/2649334/difference-between-static-and-shared-libraries

    然后在jni文件夹下创建Application.mk文件,编辑内容如下:

    # The ARMv7 is significanly faster due to the use of the hardware FPU
    APP_ABI := armeabi armeabi-v7a
    APP_PLATFORM := android-8

    其中APP_PLATFORM设定为支持的SDK最低版本。

    保存后,我们启动Cygwin,然后通过cd指令进入到我们工程的文件夹下,执行指令:$NDK/ndk-build。

    等到编译结束:

    至此so库已经生成(查看libs文件夹就会发现对应的.so文件。同时你会发现工程目录下多了一个obj文件夹,而且还不小。放心,它只是生成so文件的中间文件,不会打包到apk中)。

    接下来的任务是使用JNI调用so库进行应用层的开发了。

    应用层的开发工程一般如下:

    1. 加载so库。

    1. static {  
    2.     System.loadLibrary("webp");//loadLibrary和Android.mk中LOCAL_MODULE:= **的定义相关,我们在Android.mk中定义为webp,这里就写webp。  
    3. }  
    2.声明与Native方法相对应的方法。

    native方法是:

    1. SWIGEXPORT jint JNICALL Java_com_google_webp_libwebpJNI_WebPGetDecoderVersion(JNIEnv *jenv,  
    2.      jclass jcls) {  
    3.   jint jresult = 0 ;  
    4.   int result;  
    5.   
    6.   (void)jenv;  
    7.   (void)jcls;  
    8.   result = (int)WebPGetDecoderVersion();  
    9.   jresult = (jint)result;  
    10.   return jresult;  
    11. }  
    native方法命名规则为:Java_包名_类名_应用层方法名。其中包名中的点被下划线替代。
    应用层中需用生命的方法为:
    1. public static final native int WebPGetDecoderVersion();  
    应用层只用声明,不用定义,但要加上native关键字。

    3.使用应用层声明的方法。

    下面我们按照上述方法来在应用层使用我们刚生成的so库

    记得有一个libwebp.jar文件不,这个jar已经把应用层声明的native方法搞好了,而且帮我们封装了一层,我们只用调用其方法就ok了,但是我们还是要加载so库,因为这个它没有帮我们实现。

    我们写两个方法:

    1. static {  
    2.     System.loadLibrary("webp");  
    3. }  
    4.   
    5. private Bitmap webpToBitmap(byte[] encoded) {  
    6.   
    7.     int[] width = new int[] { 0 };  
    8.     int[] height = new int[] { 0 };  
    9.     byte[] decoded = libwebp.WebPDecodeARGB(encoded, encoded.length, width,  
    10.             height);  
    11.   
    12.     int[] pixels = new int[decoded.length / 4];  
    13.     ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);  
    14.   
    15.     return Bitmap.createBitmap(pixels, width[0], height[0],  
    16.             Bitmap.Config.ARGB_8888);  
    17.   
    18. }  
    19.   
    20. public static boolean isWebp(byte[] data) {  
    21.     return data != null && data.length > 12 && data[0] == 'R'  
    22.             && data[1] == 'I' && data[2] == 'F' && data[3] == 'F'  
    23.             && data[8] == 'W' && data[9] == 'E' && data[10] == 'B'  
    24.             && data[11] == 'P';  
    25. }  
    基于这两个方法,我们可以对webp图片进行解压缩。

    下面有一个demo,大家可以参考下:

    Webp解压缩Demo

    参考资料:

    android官方对NDK开发的介绍:http://developer.android.com/tools/sdk/ndk/index.html

    stackoverflow上一个人的经验介绍:http://stackoverflow.com/questions/7032695/webp-for-android

  • 相关阅读:
    CUBA 使用 Spring 查询接口
    Java中的数据验证
    CUBA China 最新进展
    遇见CUBA CLI
    CUBA-Platform将全面助力中国开发者
    ES6 延展操作符
    ES6 解构赋值
    Service Worker
    dom元素上添加断点(使用dom breakpoint找到修改属性的javascript代码)
    svg foreignObject的作用(文本换行,生成图片)
  • 原文地址:https://www.cnblogs.com/feitianlee/p/3994861.html
Copyright © 2011-2022 走看看