4

OpenCvを使用してJNIレイヤー上のビットマップピクセルを操作するためのパフォーマンスをテストしています。

2つのオプション:
1。整数の配列を渡し、ピクセルを操作して、ピクセルをビットマップに書き戻します。[41ms]
2.ビットマップ全体を渡します。[35ms]

ピクセル配列を渡して配列をビットマップに割り当てるよりも、ビットマップを渡す方が約5ms速いことに気づきました。

問題は、オプション2を使用すると、青が失われ、期待している青の代わりにオレンジ色になることです。画像はARGBで、RGBAに変更されたようです。何が問題になる可能性がありますか?

方法1:
Java

Bitmap out = Bitmap.createBitmap(width, height, Config.ARGB_8888);

int[] rgba = new int[width*height];

mSmasher.loadImage(imagePath, rgba, 0);

out.setPixels(rgba, 0, width, 0, 0, width, height);

JNI

JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_loadImage
    (JNIEnv *pEnv, jobject obj, jstring jFilePath, jintArray jbgra, jint options)
{
    jint*  _bgra = pEnv->GetIntArrayElements(jbgra, 0);
    const char *filePath = pEnv->GetStringUTFChars(jFilePath, 0);

    if (NULL != filePath)
    {
        // init our output image
        Mat bgra(outputHeight, outputWidth, CV_8UC4, (unsigned char *)_bgra);

                // bgra image manipulations
    }

    pEnv->ReleaseIntArrayElements(jbgra, _bgra, 0);
    pEnv->ReleaseStringUTFChars(jFilePath, filePath);
}

方法2:

JNIEXPORT void JNICALL Java_com_vblast_smasher_Smasher_getLayersBitmap
    (JNIEnv *pEnv, jobject obj, jobject bitmap)
{
    int ret;
    AndroidBitmapInfo  info;
    void*              pixels = 0;

    if ((ret = AndroidBitmap_getInfo(pEnv, bitmap, &info)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return;
    }

    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 )
    {
        LOGE("Bitmap format is not RGBA_8888!");
        return;
    }

    if ((ret = AndroidBitmap_lockPixels(pEnv, bitmap, &pixels)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    }

    // init our output image
    Mat mbgra(info.height, info.width, CV_8UC4, pixels);

    mLayers[0].copyTo(mbgra);

    AndroidBitmap_unlockPixels(pEnv, bitmap);
}

解決策05/23:
問題は、整数の配列を使用してそれをJNIに渡すときに、バイト順序がARGB(java)からBGRA(native)に変更されることでした。これは、ピクセルを操作するのに問題ありませんでした。ただし、ピクセルをロックするときに実際のビットマップオブジェクトを渡すと、バイトオーダーは変更されなかったため、ピクセルデータを変更した後に変更する必要がありました。

cvtColor(mbgra, mbgra, COLOR_BGR2RGBA, 4); 
4

2 に答える 2

3

Opencvの順序はRGBではなくBGRです。Aは正しい場所にあると思います(または半透明の画像が表示されます)が、青と赤は入れ替わります。

于 2012-05-23T00:56:34.983 に答える
1

JNIではカラー値はARGBとして返されますが、JAVAではRGBAです。これを試してください

alpha = (int) ((color & 0xFF000000) >> 24);
    blue = (int) ((color & 0xFF0000) >> 16);
    green = (int)((color & 0x00FF00) >> 8);
    red = (int) (color & 0x0000FF);
    blue = blue * alpha / 255;
    green = green * alpha / 255;
    red = red * alpha / 255;

    int tmp = 0;
    tmp = red;
    red = blue;
    blue = tmp;

    color =  ((alpha<< 24) & 0xFF000000) | ((blue<< 16) & 0xFF0000) |
                  ((green << 8) & 0x00FF00) |
                  (red & 0x0000FF);
于 2016-08-11T10:04:01.380 に答える