Я боролся с отправкой обратно CV: Mat в JNI как байт Java [], чтобы он мог быть успешно декодирован с помощью BitmapFactory.decode (). Когда я впервые привожу свой массив byte [] (созданный с использованием данных из растрового изображения Android) со стороны Java, я могу успешно использовать его в функциях C ++ OpenCV. Я делаю это, собирая Mat из байта [] и вызывая cv :: imdecode для Mat.
Проблема возникает, когда я возвращаюсь обратно в Android и пытаюсь использовать BitmapFactory для декодирования байтового массива в растровое изображение Android. Возвращает ноль, что указывает на проблему с декодированием. Я неправильно выполняю операции, прежде чем вернуться из JNI? Нужно ли использовать cv :: imencode, так как мне пришлось использовать cv :: imdecode для входного байта []?
Любая и вся помощь приветствуется! Пример кода ниже, где я конвертирую нужные мне данные из Mat в JNI.
НОТА Я знаю об использовании функций Apache Android_Bitmap, но использование байтового массива является требованием, над которым я сейчас работаю.
//inData is a char* pointer that is set to a char* cast of the jbyte* pointer for the
// incoming Array.
cv::Mat inMat = cv::Mat(rows, columns, CV_8UC4, inData);
cv::Mat decodedMat = cv::imdecode(inMat, 1);
//convertImage is a function that changes the color space from BGR to Gray and then Gray to
//RGB.
convertImage(decodedMat, decodedMat);
cv::cvtColor(decodedMat, decodedMat, CV_RGB2RGBA);
jbyteArray jDataArray = env->NewByteArray(pixelDataLength);
env->SetByteArrayRegion(jDataArray,0,pixelDataLength,(jbyte*)decodedMat.data);
env->SetObjectField(in,dataArray,jDataArray);
env->ReleaseByteArrayElements(pixelData, bytePointerForIn, 0);
BitmapFactory ожидает, что предоставленные ему данные будут в известном формате файла, но вы передаете ему необработанные пиксели. Вы можете заставить его работать, вызывая cv :: imencode, но, возможно, более естественным решением для загрузки изображений из необработанных пиксельных данных будет создание исходного объекта Java Bitmap как изменяемого, а затем вызовы методов copyPixelsToBuffer и copyPixelsFromBuffer для получения и установки данные пикселей в этом объекте.
Решено! Это была комбинация моей исходной версии отправки в байтах с помощью Bitmap.compress (), а затем в возвращаемых пикселях с помощью copyPixelsFromBuffer. Спасибо Бадди за то, что он указал мне правильное направление.
Android:
//input was the original bitmap that was used to construct the byte[] array. I then used input.compress() in JPEG format to a Byte. Very important for it to be compressed in a format that will be recognized in cv::imdecode.
ByteArrayOutputStream bos = new ByteArrayOutputStream();
input.compress(CompressFormat.JPEG, 100, bos);
data1.pixelData = bos.toByteArray();
...
//Reconstruction after JNI call
ByteBuffer buffer2 = ByteBuffer.wrap(data1.pixelData);
Bitmap returnFromConvert = Bitmap.createBitmap(input.getWidth(),
input.getHeight(),Bitmap.Config.ARGB_8888);
returnFromConvert.copyPixelsFromBuffer(buffer2);