encode bitmap to webp with libwebp on Android pre api 14 device

冷暖自知 提交于 2019-12-25 03:13:16

问题


I want to encode Bitmap to webp on Android 2.x device with libwebp. Below is my testing code

public static int createWebPImage(Bitmap bitmap, String outFilePath) {
    Log.d(TAG, "create webp image");
    ByteBuffer buffer = ByteBuffer.allocateDirect(BitmapCompat.getAllocationByteCount(bitmap));
    bitmap.copyPixelsToBuffer(buffer);
    return nativeCreateWebPImage(buffer, bitmap.getWidth(), bitmap.getHeight(), outFilePath);
}

And the jni implementation is

nativeCreateWebPImage(JNIEnv *env, jclass type, jobject directBuffer, jint width, jint height, jstring outFilePath_) {
    const char *outFilePath = env->GetStringUTFChars(outFilePath_, 0);
    int ret = 0;
    FILE* file = NULL;
    if ((file = fopen(outFilePath, "w+")) != NULL) {
        uint8_t* buffer = (uint8_t *) env->GetDirectBufferAddress(directBuffer);
        LOGD("size of the bitmap %lu", (unsigned long) env->GetDirectBufferCapacity(directBuffer));
        uint8_t* output = (uint8_t *) malloc((size_t) env->GetDirectBufferCapacity(directBuffer));
        size_t n = WebPEncodeRGBA(buffer, width, height, width, 0.9, &output);
        if (n <= 0) {
            LOGD("webp encode failed");
            ret = -1;
        } else {
            LOGD("write to file");
            if (fwrite(output, sizeof(uint8_t), n, file) != n) {
                LOGD("write file error");
                ret = -1;
            }
        }

        free(output);
        fclose(file);
    } else {
        LOGD("open file error %s", outFilePath);
        ret = -1;
    }
    env->ReleaseStringUTFChars(outFilePath_, outFilePath);
    return ret;
}

The resulting file was created successfully, but the encoded image was totally broken. The image seems filled with the wrong data. Is the parameters wrong when calling WebPEncodeRGBA? The bitmap configuration is Bitmap.Config.ARGB_8888.

How can I correctly encode Bitmap to webp with the API call WebPEncodeRGBA?


回答1:


After read the docs from Google, I found the stride parameter was wrong. It should be counted as bytes. Then I changed the encode function call to

WebPEncodeRGBA(buffer, width, height, width * 4 /* stride in bytes */, 0.9, &output);

It worked.



来源:https://stackoverflow.com/questions/34632379/encode-bitmap-to-webp-with-libwebp-on-android-pre-api-14-device

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!