将 libwebp 与 NDK 一起使用。
libwebp-0.1.3 已经带有 Android.mk 文件(已过时且存在语法错误,但仍然存在)。它还在/swig/ 目录中生成了JNI 绑定。
这是我的工作原理:
- 下载NDK,放入系统
PATH。
- 下载libwebp-0.1.3.tar.gz,放在
your_project_dir/jni
- 将
Android.mk 替换为下面的那个。
- 使用下面的内容创建
jni/src/libwebp_java_wrap.c。
- 创建
jni/Application.mk,内容来自下方。
- 从项目目录运行
ndk-build。这会在/libs/ 中生成.so 文件。您可以使用nm -D libs/armeabi/libwebp.so 检查它们。在列表中,您将看到原生库函数(如 WebPDecodeRGB)和它们的 JNI 对应函数(如 Java_com_google_webp_libwebpJNI_WebPDecodeRGB)
- 将
/jni/swig/libwebp.jar 添加到您的Android 项目的构建路径
- 参见下文,了解如何在 Java 代码中使用它
这是 Android.mk 的内容。从原始更改:删除编码器位,因为我不需要这些,添加 libwebp_java_wrap.c,将 include $(BUILD_STATIC_LIBRARY) 更改为 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)
libwebp_java_wrap.c 的内容是here,它与捆绑在 libwebp tarball 中的内容基本相同,只是删除了编码器位。
Application.mk 的内容:
# The ARMv7 is significanly faster due to the use of the hardware FPU
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-9
以下是如何在 Java 代码中使用。请注意它是如何将 byte[] 数组转换为 int[] 颜色数组的——如果字节顺序发生变化,这将中断,对吧?还要注意它是如何使用数组而不是单个整数来表示宽度和高度的,因此它们是通过引用传递的。
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);
}