WebP for Android
Use libwebp with NDK.
libwebp-0.1.3 already comes with Android.mk file (outdated and with syntax errors, but still). It also got generated JNI bindings in /swig/
directory.
Here's how I got it working:
- Download NDK, put it in system
PATH
. - download libwebp-0.1.3.tar.gz, place it in
your_project_dir/jni
- Replace
Android.mk
with the one below. - Create
jni/src/libwebp_java_wrap.c
with content from below. - create
jni/Application.mk
, with content from below. - run
ndk-build
from project directory. This generates.so
files in/libs/
. You can inspect them withnm -D libs/armeabi/libwebp.so
. In the list you'll see both the native library functions (likeWebPDecodeRGB
) and their JNI counterparts (likeJava_com_google_webp_libwebpJNI_WebPDecodeRGB
) - Add
/jni/swig/libwebp.jar
to build path of your Android project - See below for example how to use it in Java code
Here's content for Android.mk. Changed from original: removed encoder bits as I don't need these, added libwebp_java_wrap.c
, changed include $(BUILD_STATIC_LIBRARY)
to include $(BUILD_SHARED_LIBRARY)
.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
src/dec/alpha.c \
src/dec/frame.c \
src/dec/idec.c \
src/dec/layer.c \
src/dec/quant.c \
src/dec/tree.c \
src/dec/vp8.c \
src/dec/webp.c \
src/dec/io.c \
src/dec/buffer.c \
src/dsp/yuv.c \
src/dsp/upsampling.c \
src/dsp/cpu.c \
src/dsp/dec.c \
src/dsp/dec_neon.c \
src/dsp/enc.c \
src/utils/bit_reader.c \
src/utils/bit_writer.c \
src/utils/thread.c \
src/libwebp_java_wrap.c \
LOCAL_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD -DWEBP_USE_THREAD \
-finline-functions -frename-registers -ffast-math \
-s -fomit-frame-pointer -Isrc/webp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_MODULE:= webp
include $(BUILD_SHARED_LIBRARY)
Content for libwebp_java_wrap.c is here, it's basically the same as bundled in libwebp tarball, except encoder bits removed.
Content for Application.mk:
# The ARMv7 is significanly faster due to the use of the hardware FPU
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-9
Here's how to use in Java code. Notice how it converts byte[] array to int[] color array--this will break if endianness changes, right? Also notice how it uses arrays instead of single integers for width and height so they are passed by reference.
static {
System.loadLibrary("webp");
}
private Bitmap webpToBitmap(byte[] encoded) {
int[] width = new int[] { 0 };
int[] height = new int[] { 0 };
byte[] decoded = libwebp.WebPDecodeARGB(encoded, encoded.length, width, height);
int[] pixels = new int[decoded.length / 4];
ByteBuffer.wrap(decoded).asIntBuffer().get(pixels);
return Bitmap.createBitmap(pixels, width[0], height[0], Bitmap.Config.ARGB_8888);
}
WebP is supported for Android 4.0+, a.k.a. API level 14. You can check using
android.os.Build.VERSION.SDK_INT >= 14
.