6

I'm planning to take a picture by camera phone (Android) then pass it to C function through JNI. The C function is generated by MATLAB Coder.

Here is the header of the generated C function:

real_T detection(const **uint8_T** OriginalImage[28755648])

Here is the data type of the image:

 @Override
    public void onPictureTaken(**byte[] data**, Camera camera) {.....}

Question: How to convert byte[] to uint8_T array? I found how to convert byte[] to jbyte *.. but I don't know how to deal with uint8_T?

I know only Java but not C.

Regards,

Community
  • 1
  • 1
user3020258
  • 63
  • 1
  • 4
  • 1
    why do you want so, you are trying to convert byte[] to unsigned char array, its range is within 0-255 – Viswanath Lekshmanan Nov 22 '13 at 05:13
  • @Arju I (have) to convert it because most of the time, we cannot just use Java data types directly in C. For example, we have to convert java.lang.String to char * before we can effectively use it in C. Am I missing something? – user3020258 Nov 22 '13 at 19:32

1 Answers1

7

Java does not have unsigned integer types, but the camera does not really care. You can safely cast the byte array that arrives from onPictureTaken() callback to uint8_t*.

Sidenote: most likely, the picture will arrive as JPEG stream.

Update: Example of implementing onPictureTaken() in C.

Here is what you have somewhere in your activity:

mCamera = Camera.open();
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
...
mCamera.takePicture(null, null, new android.hardware.Camera.NativePictureCallback);

Here is the file src/android/hardware/Camera/NativePictureCallback.java:

package android.hardware.Camera;
class NativePictureCallback: implements PictureCallback {
  static { 
    System.loadLibrary("NativeCamera"); 
  } 
  public void native onPictureTaken(byte[] data, Camera camera);
}

And here is the C file that is part of libNativeCamera.so:

include <jni.h>
include <tmwtypes.h>

real_T detection(const uint8_T* OriginalImage);

JNIEXPORT void JNICALL
Java_android_hardware_Camera_NativePictureCallback_onPictureTaken(
    JNIEnv* env, jobject thiz, jbytearray data, jobject camera) {
  jbyte* dataPtr = (*env)->GetByteArrayElements(env, data, NULL);
  real_T res = detection((const uint8_T*)dataPtr);
  (*env)->ReleaseByteArrayElements(env, data, dataPtr, JNI_ABORT);
}
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • could you please give me an example to make it more clear for me? Should I do the casting inside onPictureTaken()? If yes, how to do it while uint8_t* is not supported in Java. Thanks – user3020258 Nov 25 '13 at 21:32
  • @zharf I found your answer here: http://stackoverflow.com/a/16668081/3020258 which is related to my question except that I have a C code and yours is C++. Could you please help me what are the changes that I should make to make it suitable for my code? – user3020258 Nov 26 '13 at 00:42
  • Oh, you need complete code for the wrapper… See the updated answer as soon as I find a full-sized keyboard to type it. – Alex Cohn Nov 29 '13 at 06:08
  • @user3020258: I have updated the answer with complete code for the wrapper. – Alex Cohn Dec 01 '13 at 21:11
  • I really appreciate your help. I want to make sure I understand the process. You provided me with 3 codes. #1-I put it in MainActivity.java . #2- I created new java class & added your code(This class has only the code u provided right?)(the colon before implements is typo?). #3-This code should be placed in C file, so the C file will have the C implementation of "detection" & JNICALL of onPictureTaken? Also how can I return the parameter from C to java while the return type of JNICALL is void?! Thank you so much – user3020258 Dec 07 '13 at 05:18
  • also is there another way of making the onPictureTaken function as a Native? Since I need to make the C function receives (the captured image, two images stored in res/drawable in Eclipse, and a number) and I think if I follow your code I wont be able to make it since I cannot change the header of onPictureTaken. – user3020258 Dec 07 '13 at 05:29
  • My example does not allow for additional parameters, return value, or other modifications. If you want any of those, you have to reconsider the architecture. I would suggest that you start with a pure Java program that makes a fake call to `real_T detection()`, and when you are satisfied with that (consider synchronization, multithreading, state machines, etc.), only then imlement the JNI call. – Alex Cohn Dec 07 '13 at 09:01
  • 1
    Even I didn't exactly follow your solution,I accepted it since it was an excellent start point and hint for me. Thank you for ur help and fast response! I only used the third code. – user3020258 Dec 07 '13 at 12:32