JNI:来自unsigned char *的位图始终为null

时间:2015-07-01 16:10:56

标签: java android c++ bitmap java-native-interface

我想将图像(通过jni)从C ++传递到Android应用程序。我从一个unsigned char*数组开始。这个数组没有任何损坏;我甚至可以将其保存到ppm文件中并在我的笔记本电脑上正确显示。

然后,我使用此函数将其转换为jByteArray

jbyteArray imgByte=as_byte_array(env,imgRaw,img.getRawImageSize());
...
jbyteArray as_byte_array(JNIEnv *env, unsigned char* buf, int len) {
    jbyteArray array = env->NewByteArray (len);
    env->SetByteArrayRegion (array, 0, len, reinterpret_cast<jbyte*>(buf));
    return array;
}

之后,我将此jByteArray发送到java端。已正确填充此变量,我可以通过在LogCat上打印其十六进制值来看到:

07-01 18:02:45.941    7017-8238/com.myapp.myapp W/C++ side﹕  798a95798b9677889371838d6b7d8664757e5d6e7860717b5e...
07-01 18:02:46.941    7017-8238/com.myapp.myapp W/Java side﹕ 798a95798b9677889371838d6b7d8664757e5d6e7860717b5e...

最后一步是在ImageView上显示它。为此,我执行以下代码(取自另一个关于SO的问题):

public void setImageViewWithByteArray(final ImageView view, byte[] data) {
    final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

    getActivity().runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (bitmap==null) {
                Log.e(TAG,"Bitmap is NULL!");
                view.setImageResource(R.drawable.abc_btn_radio_material);
            }
            else {
                view.setImageBitmap(bitmap);
            }
        }
    });
}

bitmap变量始终为null。我究竟做错了什么?有没有办法调试decodeByteArray

1 个答案:

答案 0 :(得分:4)

BitmapFactor.decodeByteArray用于解码压缩的图像数据,例如PNG文件的内容。

如果您的字节数组包含未压缩的RGB数据,那么您可以create a mutable Bitmap使用正确的宽度和高度,然后使用Bitmap.setPixels设置像素。但是,setPixels采用具有32位ARGB值的整数数组,并且从您的日志中看起来您的字节数组包含每像素3个字节的RGB数据。

所以你需要创建一个int数组,然后处理你的字节数组,并为每个字节三元组的int数组写一个int值,例如:

intArray[i] = 0xff000000 |
    (((int)data[i*3] & 255) << 16) | (((int)data[i*3+1] & 255) << 8) | ((int)data[i*3+2] & 255);

然后将其传递给setPixels。或者您可以在JNI端执行此操作并返回jintArray。