title: Android JNI: convert cv::Mat to jbyteArray
body: <p>I have C/C++ source code (run well on Windows) to convert an input frame to new frame. </p>
  
  <p>Now i want to porting this C/C++ source code to my Android application to convert frame of device Camera2.</p>
  
  <p>I will get continuous byte[] frame of Camera2 from Java app then input it to JNI to received converted byte new_frame.</p>
  
  <p>So my flow in JNI must be:</p>
  
  <ol>
  <li><p>Convert byte[] frame from Java to JNI jarrayByte </p></li>
  <li><p>Convert jarrayByte to jyte*</p></li>
  <li><p>Create new cv::Mat original from jbyte*</p></li>
  <li><p>Convert input cv::Mat orignal to new cv::Mat converted using C/C++ function</p></li>
  <li><p>Now, i need to convert back cv::Mat converted to jByteArray to return Java function => i'm stucking at this step  </p></li>
  </ol>
  
  <p>So my question is how to convert back cv::mat to jbyteArray to return Java layer of application?</p>
  
  <pre><code>extern "C" JNIEXPORT jbyteArray
  JNICALL
  Java_com_xyz_NativeUtil_convertFrame(JNIEnv *env, jobject obj,
                                                                    jbyteArray yuvFrame) {
  // convert jByteArray to jbyte*
  jbyte* yuvByte = env-&gt;GetByteArrayElements(yuvFrame, 0);
  // convert jbyte* to cv::Mat
  cv::Mat frame_original_yuv = cv::Mat(height + height/2, width, CV_8UC1, yuvByte);
  // convert YUV cv::Mat to RGBA cv::Mat
  cv::Mat frame_original_rgba = cv::Mat(height, width, CV_8UC4);
  cv::cvtColor(frame_original_yuv, frame_original_rgba, CV_YUV2RGBA_NV21);
  env-&gt;ReleaseByteArrayElements(yuvFrame, yuvByte, 0);
  // convert frame
  cv::Mat frame_converted = convert_frame(frame_original_rgba);
  frame_original_yuv.release();
  
  if (frame_converted .empty()) {
      frame_converted = frame_original_rgba;
  }
  frame_original_rgba.release();
  // convert cv::Mat to jbyteArray
  jbyteArray result = ???
  
  return result;
  </code></pre>
  
  <p>}</p>
  
  <p>My Java code:</p>
  
  <pre><code>mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
              @Override
              public void onImageAvailable(ImageReader reader) {
                  Image image = reader.acquireLatestImage();
                  if (image == null)
                      return;
  
                  Image.Plane Y = image.getPlanes()[0];
                  Image.Plane U = image.getPlanes()[1];
                  Image.Plane V = image.getPlanes()[2];
  
                  int Yb = Y.getBuffer().remaining();
                  int Ub = U.getBuffer().remaining();
                  int Vb = V.getBuffer().remaining();
  
                  byte[] yuvFrame = new byte[Yb + Ub + Vb];
  
                  Y.getBuffer().get(yuvFrame, 0, Yb);
                  U.getBuffer().get(yuvFrame, Yb, Ub);
                  V.getBuffer().get(yuvFrame, Yb + Ub, Vb);
  
                  image.close();
              }
          }, mBackgroundHandler);
  </code></pre>