кодировать растровое изображение в webp с помощью libwebp на устройстве Android до API 14

Я хочу закодировать Bitmap в webp на устройстве Android 2.x с помощью libwebp. Ниже мой тестовый код

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);
}

И реализация jni

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;
}

Результирующий файл был успешно создан, но закодированное изображение было полностью повреждено. Изображение кажется заполненным неправильными данными. Неверные параметры при вызове WebPEncodeRGBA? Конфигурация растрового изображения — Bitmap.Config.ARGB_8888.

Как я могу правильно закодировать Bitmap в webp с помощью вызова API WebPEncodeRGBA?


person alijandro    schedule 06.01.2016    source источник
comment
до API 14 в настоящее время (по состоянию на 6 января 2016 г.) 3,2% устройств имеют доступ к Google Play ( developer.android.com/about/dashboards/index.html ). Вы уверены, что хотите доставить все эти неприятности такому маленькому населению?   -  person Budius    schedule 06.01.2016
comment
@Budius В настоящее время я сжимаю растровое изображение в jpeg на устройстве Android 2.x, поэтому, если эта проблема не может быть решена, я буду продолжать использовать jpeg на устройстве Android 2.x. Причина, по которой я предпочитаю webp, заключается в том, что размер меньше, чем jpeg.   -  person alijandro    schedule 06.01.2016


Ответы (1)


Прочитав документы от Google, я обнаружил, что параметр шага неверен. Это должно считаться как байты. Затем я изменил вызов функции кодирования на

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

Это сработало.

person alijandro    schedule 07.01.2016