我一直在努力将CV:Mat作为Java发送回JNI,这样就可以用BitmapFactory.decode()成功地解码它。当我第一次从Java端引入我的byte[]数组(使用Android中的数据构建)时,我能够在C++ OpenCV函数中成功地使用它。为此,我从进来的byte[]构建一个Mat,并在Mat上调用cv::imdecode。
当我返回到Android并尝试使用BitmapFactory将字节数组解码为Android位图时,问题就出现了。它返回null,这表明在解码过程中存在问题。在从JNI返回之前,我是否不正确地执行这些操作?是否需要使用cv::imencode,因为在输入byte[]时必须使用cv::imdecode?
任何和所有的帮助感谢!代码示例下面是我从JNI中的Mat转换所需数据的地方。
注意到我知道使用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);
发布于 2014-04-15 12:41:43
解决了!它结合了我使用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);
发布于 2014-03-28 14:59:39
BitmapFactory希望提供给它的数据是一种已知的文件格式,但是您要将它传递给原始像素。您可以通过调用cv::imencode来使其工作,但是从原始像素数据加载图像的一个更自然的解决方案可能是将原始的Java对象创建为可变的,然后调用copyPixelsToBuffer和copyPixelsFromBuffer方法来获取和设置该对象中的像素数据。
https://stackoverflow.com/questions/22723725
复制相似问题