问题
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