安卓的WebP技术

24
有没有关于如何在Android上使用WebP的示例? 我正在尝试获取WebP图像列表并在ListView中显示它们,其中包括一个ImageView。
我知道有libwebp API,并且已经使用NDK将其集成到我的Android项目中,但是我应该如何使用API来将二进制WebP显示在ImageView中?
任何帮助都将不胜感激!

2
在最新的Android Studio 2.3+中,您现在可以直接将图像转换为webp格式的图像。 - bebe
5个回答

29

如何使用NDK构建libwebp,libwebp-0.1.3已经带有Android.mk文件(过时且存在语法错误,但仍然可用),并在/swig/目录中生成了JNI绑定。

  1. 下载NDK,并将其放置在系统的PATH中。
  2. 下载libwebp-0.1.3.tar.gz,将其放置在your_project_dir/jni目录中。
  3. 使用下面的内容替换Android.mk文件。
  4. 创建jni/src/libwebp_java_wrap.c文件,并将下面的内容复制到文件中。
  5. 创建jni/Application.mk文件,并将下面的内容复制到文件中。
  6. 从项目目录中运行ndk-build命令。这会在/libs/目录下生成.so文件。您可以使用nm -D libs/armeabi/libwebp.so命令检查它们。在列表中,您将看到本地库函数(如WebPDecodeRGB)及其JNI对应函数(如Java_com_google_webp_libwebpJNI_WebPDecodeRGB)。
  7. /jni/swig/libwebp.jar添加到Android项目的构建路径中。
  8. 查看下文中的示例,了解如何在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 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);

}

有没有一个示例项目可以在安卓上展示WebP图片,就像你在这里做的一样? - android developer
2
我已经成功地按照Pēteris上面的步骤完成了这个项目,适用于最新的WebP src(0.2.0)。和Pēteris一样,我不需要编码支持,所以我的更新后的Android.mk和libwebp_java_wrap.c可以在https://gist.github.com/3719812上找到。 - Mark Beaton
3
谢谢你们!这太棒了!("Thanks a million"是一种表达感激之情的固定用语,意为“非常感谢”或“万分感谢”) - geomaster
还有针对动画WEBP的东西吗? - android developer
我想尝试使用这个工具来制作动态webp,可以调整大小并将gif转换为webp。 - CrackerKSR
@CrackerKSR 注意,这是一个11年前的答案,当时WebP还很新,并且尚未被Android原生支持。 - Pēteris Caune

15

WebP被Android 4.0+(即API级别14)支持。您可以使用android.os.Build.VERSION.SDK_INT >= 14进行检查。


4

谷歌声称WebP从Android 4.0+开始得到支持(http://developer.android.com/guide/appendix/media-formats.html),但在我们自己的测试中,WebP图像在Android 4.0和4.1上在标准浏览器和Chrome中显示为蓝色问号。

在Android 4.2中,WebP图像似乎可以在webview和Google Chrome中正确呈现。


1
他们在那份文档中提到,无损和透明度只适用于4.2.1及以上版本。我猜测没有透明度的有损图像适用于4.0及以上版本。 - Chris.Jenkins

4
我们为此编写了一个Android库。 https://github.com/EverythingMe/webp-android webp-android是我们在EverythingMe使用的库,因为我们喜欢webp。我们使用它来节省带宽并缩小APK大小。
webp-android是基于Chromium的webp解码器进行改编,并添加了一个JNI包装器,以便在您的Java代码中轻松使用它。 还可以使用包含的WebpImageView,轻松从XML加载webp图像到ImageView中,如下所示:
<me.everything.webp.WebpImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  webp:webp_src="@drawable/your_webp_image" />

你说得对,已编辑。 - Rotemmiz
很好,你创建了一个库,但是你能否也创建一个指南来说明如何添加这个库呢?因为即使我将输出的 .aar 文件放到我的项目的 libs 目录下,仍然没有任何反应。如何让 Android Studio 看到它并将其视为库呢? - careful7j

1

目前在 Android 设备上的任何原生应用程序,包括 Web 浏览器,都无法显示 WebP 图像。 您需要查找第三方应用程序来显示这些图像。

根据 WebP 邮件列表,他们正在努力将 WebP 支持纳入 Android SDK 中。 他们并没有说计划何时发布此功能,但是当他们发布时,您应该能够将位图保存为 WebP 格式以及 JPEG 和 PNG 格式。

编辑:Android 4.0(也称为冰淇淋三明治)现在具有 WebP 格式的本机支持。 您可以在 Android 开发人员网站 上查看支持的文件类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接