Ответ 1
Используйте libwebp с NDK.
libwebp-0.1.3 уже поставляется с файлом Android.mk(устаревшим и с синтаксическими ошибками, но все же). Он также получил сгенерированные привязки JNI в каталоге /swig/
.
Вот как я получил работу:
- Загрузите 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
из каталога проекта. Это создает файлы.so
в/libs/
. Вы можете проверить их с помощью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 здесь, оно в основном такое же, как в комплекте с архивом libwebp, кроме удаленных битов кодировщика.
Содержимое 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);
}