Home > Enterprise >  Converting jByteArray to OpenCV Mat (and viceversa) into DLL causes OutOfMemoryError
Converting jByteArray to OpenCV Mat (and viceversa) into DLL causes OutOfMemoryError

Time:01-29

First of all, say that I'm not an expert in C .

I develop a Java program that needs a process with OpenCV through a DLL. Theoretically, all components work and the result is successful except that for each call to DLL functions the memory usage increments to the point of causing an OutOfMemoryError. Actually, the Task Manager of Windows shows that the memory is above 1GB when regular use should not greater than 100MB.

I have commented on parts to corner the problem and all point to the that the problem is in converting from byte array to Mat and vice-versa into DLL.

I suspect that the memory management is not correct but I don't know how to do it in DLL.

Both functions code is:

cv::Mat getMat(JNIEnv* env, jint width, jint height, jbyteArray arr) {
    unsigned char* isCopy = new unsigned char[width * height];
    jbyte* jbae = env->GetByteArrayElements(arr, isCopy);
    jsize len = env->GetArrayLength(arr);
    char* imageSource = (char*)jbae;
    std::vector<char> captureVector;
    for (int i = 0; i < len; i  ) {
        captureVector.push_back(imageSource[i]);
    }
    return cv::imdecode(captureVector, cv::IMREAD_COLOR);
}
jbyteArray getJBytes(JNIEnv* env, cv::Mat mat) {
    std::vector<unsigned char> imageDesV;
    imencode(".bmp", mat, imageDesV);
    jbyte* result_e = new jbyte[imageDesV.size()];
    jbyteArray result = env->NewByteArray(imageDesV.size());
    for (unsigned int i = 0; i < imageDesV.size(); i  ) {
        result_e[i] = (jbyte)imageDesV[i];
    }
    env->SetByteArrayRegion(result, 0, imageDesV.size(), result_e);
    return result;
}

Any help would be most welcome.

Many thanks in advance. Alex

CodePudding user response:

Thanks Dan,

The solution was this:

cv::Mat getMat(JNIEnv* env, jint width, jint height, jbyteArray arr) {
    jbyte* jbae = env->GetByteArrayElements(arr, nullptr);
    jsize len = env->GetArrayLength(arr);
    std::vector<char> captureVector;
    for (int i = 0; i < len; i  ) {
        captureVector.push_back(jbae[i]);
    }
    env->ReleaseByteArrayElements(arr, jbae, JNI_ABORT);
    cv::Mat mat = cv::imdecode(captureVector, cv::IMREAD_COLOR);
    return mat;
}
jbyteArray getJBytes(JNIEnv* env, cv::Mat mat) {    
    std::vector<unsigned char> imageDesV;
    imencode(".bmp", mat, imageDesV);
    jbyte* result_e = new jbyte[imageDesV.size()];
    jbyteArray result = env->NewByteArray(imageDesV.size());
    for (unsigned int i = 0; i < imageDesV.size(); i  ) {
        result_e[i] = (jbyte)imageDesV[i];
    }
    env->SetByteArrayRegion(result, 0, imageDesV.size(), result_e);
    delete[]result_e;
    return result;
}
  • Related