Я тестирую производительность для управления растровыми пикселями на уровне JNI с использованием OpenCv.NDK Обработка растровых изображений с использованием цвета OpenCv оранжевого цвета?
два варианта:
1. Проход массив целых чисел, манипулировать пикселей и записывать пиксели обратно в Bitmap. [41ms]
2. Пропустите весь растровый рисунок. [35ms]
Я заметил, что это примерно на 5 мс быстрее, чтобы передать битмап, чем передать массив пикселей и назначить массив битмапу.
Проблема в том, что с использованием опции 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 (родной). Это было прекрасно для работы с пикселями. Однако, передавая фактический объект Bitmap при блокировке пикселей, порядок байтов не изменялся, поэтому ему необходимо было изменить его после изменения данных пикселя.
cvtColor(mbgra, mbgra, COLOR_BGR2RGBA, 4);
Я заинтересован в ваших тестах скорости. Не могли бы вы обобщить оба метода, я не понимаю, что подразумевается в первом. –
Добавлено несколько деталей ... Надеюсь, что это имеет смысл :) – Jona