3

I'm using OpenCv through the Android NDK (using c++) I would like to save an image into MAT format and then display it on my android application.

I have saved the image in assets. imread() does not work in the NKD because it cannot find the file path to the image, however, I can use AssetManager to load an asset and it finds the path perfectly. This method saves the data into a char* buffer.

How can I, either use something similar to imread() to save the image into a MAT, or convert the char* buffer data into a MAT in order to display it on screen and later on manipulate with other openCV functions?

Ramesh sambu
  • 3,577
  • 2
  • 24
  • 39
Ber12345
  • 89
  • 1
  • 12
  • [`cv::imdecode`](https://docs.opencv.org/3.3.0/d4/da8/group__imgcodecs.html#ga26a67788faa58ade337f8d28ba0eb19e) is the equivalent of `imread` when you already have the data in a buffer. – Dan Mašek Dec 13 '17 at 17:34
  • @Dan Mašek my code is in the format : char* buffer = (char*) malloc (sizeof(char)*sizeOfImg); AAsset_read(img, buffer, sizeOfImg); so the resulting buffer is in the form char*. imdecode() expects data in the format const_inputArray. – Ber12345 Dec 13 '17 at 17:42
  • 2
    put the data in a `std::vector` and use `cv::imdecode` – Miki Dec 13 '17 at 18:38
  • 2
    Don't even have to copy the data to a vector: [`cv::_InputArray(buffer,buffer_size)`](https://docs.opencv.org/3.3.1/d4/d32/classcv_1_1__InputArray.html#af5fefc8554c4df2697f83033753799e7) – Dan Mašek Dec 13 '17 at 19:05

1 Answers1

0

Use code snippet

extern "C"
JNIEXPORT int JNICALL
Java_com_example_opencv_test_NativeLib_checkNativeImage(JNIEnv *env,
                                                    jclass type,
                                                    jobject jBitmap,
                                                    jint width,
                                                    jint height) {

void *pPixelData = nullptr;
if (AndroidBitmap_lockPixels(env, jBitmap, &pPixelData) ==
    ANDROID_BITMAP_RESULT_SUCCESS) {

    // Android bitmap (Bitmap.Config.ARGB_8888) to Mat
    // Android and OpenCV have different color channels order, just swap it
    // You need cppFlags "-std=c++14" for this code
    // See [opencv_src]\modules\java\generator\src\cpp\utils.cpp for details about PremultiplyAlpha
    // Use https://docs.opencv.org/java/2.4.2/org/opencv/android/Utils.html for Mat in Java

    cv::Mat temp = cv::Mat(cvSize(width, height), CV_8UC4, pPixelData); // 4 channels
    cv::Mat img;
    cv::cvtColor(temp, img, CV_BGRA2RGBA);

    // ... use Mat Image


    // back to Android Bitmap
    cvtColor(img, temp, CV_RGBA2BGRA); // Swap colors back
    memcpy(pPixelData, temp.data, static_cast<size_t>(width * height * 4));


    AndroidBitmap_unlockPixels(env, jBitmap);

    return EXIT_SUCCESS;
}

return EXIT_FAILURE;

}
AndreyICE
  • 3,574
  • 29
  • 27