Reputation: 389
I am developing an aplication where I need to read large image files (6000x6000) ,then applying some filtering (like blurring and color effects) and then saving the image. The filtering library is a 3rd party library that is programmed in Java and take something like this as a input :
/**
* rgbArray : is an Array of pixels
*/
public int[] ImageFiltering(int[] rgbArray,int Width,int Height);
The problem is that if I load the image in memory (6000 x 6000 x 4 = 137.33 MB) android throws OutOfMemory error. After reading some documentation and knowing that the memory allocated from NDK is not part of the application heap ,I get an interesting idea:
Open the image from NDK Read it contents and save it in an array
Pass the array back to Java
Apply filter to the array data
Return the array to NDK
Save the data array into a new image and release the array memory
Here is an example of NDK function with returns the big,fat array:
jint*
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,jobject thiz,jint w,jint h)
{
int* pixels = (int*)malloc(w * h * 4);
read_image_into_array("image.jpg",pixels);
return pixels;
}
The goal is to reserve the memory in native in order to avoid getting OutOfMemory error,and pass the memory reference to Java in order to work with it. Since I am have not C developer and have never touched JNI ,is all this making sense and how could it be implemented in NDK.
Upvotes: 1
Views: 1236
Reputation: 10069
Use a direct ByteBuffer, using the allocated memory as its backing buffer. You can allocate a direct byte buffer from JNI (using NewDirectByteBuffer()
) and return it.
You'll need to provide a complementary method for disposing of the memory or otherwise indicating to the native side that it is no longer in use.
Upvotes: 1