【问题标题】:Passing a byte array from JNI directly in Android bitmap在Android位图中直接从JNI传递一个字节数组
【发布时间】:2013-01-11 10:56:30
【问题描述】:

我在 JNI 中有一个灰度图像作为字节数组,我需要将它传递给 Android 以显示在屏幕上。目前我的代码如下:我将字节数组复制到JNI中的一个int数组,然后用该数组设置Bitmap的像素:

JNI 端:

jintArray frame = g_env->NewIntArray(frameSize);
int tempFrame[frameSize];
for(int pix = 0; pix < frameSize; pix++){
    //convert every byte to int
    jint greyValue = 0xff000000 | (( byteArray[pix] << 16) & 0xffff0000) | ((byteArray[pix] << 8) & 0xff00ff00) | (byteArray[pix] & 0xff0000ff);
    tempFrame[pix] = greyValue;
}
g_env->SetIntArrayRegion(frame, 0, frameSize, tempFrame);

//return the array setting a variable in java
g_env->SetObjectField(g_o, g_env->GetFieldID(g_class, "mFrame", "[I"), frame);

那么,Java 端:

//Somewhere in SurfaceView.surfaceCreated method
if(mBitmap == null)
    mBitmap = Bitmap.createBitmap(mImageWidth, mImageHeight, Bitmap.Config.ARGB_8888);

//Somewhere in View.onDraw method
if(mBitmap != null && nativeClass.mFrame != null){
    mBitmap.setPixels(nativeClass.mFrame, 0, mImageWidth, 0, 0, mImageWidth, mImageHeight);

    //Do some operations on the bitmap with mBitmap.setPixel()

    canvas.drawBitmap(mBitmap, srcRect, dstRect, null);
}

我想知道是否有一种方法可以加快进程,避免复制数组两次(首先从 jintArray 到 int[],然后从 int[] 到 Bitmap),例如直接在 Bitmap 中写入,或者通过在 JNI 中创建一个位图并将其传递给 Android。 (我知道canvas有一个drawBitmap方法接受int[]而不是Bitmap,但是那个方法不接受Rects进行缩放,所以不可行)

【问题讨论】:

    标签: android bitmap java-native-interface


    【解决方案1】:

    简单的方法:

    在 Java 代码中创建位图。 在本机代码中传递位图引用。 使用AndroidBitmap_lockPixels 获取像素值数组。 用数据填充数组。 最后拨打AndroidBitmap_unlockPixels

    Hard way.

    【讨论】:

    • 恐怕我不能...我使用回调函数从另一个线程接收图像。 ...不过,我可以在其他一些函数中初始化位图引用,所以我会尝试的。我不相信这种艰难的方式,我似乎记得从 jni 调用 java 方法的计算成本很高,但我也会检查一下。
    • PS:我按照简单的方法做了,它可以正常工作;认为它给我的参考表带来了一些问题......但这是一个不同的问题,所以我将为此提出另一个问题。
    猜你喜欢
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    相关资源
    最近更新 更多