Hello experts,
I'm using opencv 2.4.2 with ndk r7b and I use the following function to convert an IplImage to int array, so that an image which is loaded by the native code can be passed to the Java code.
My native code is as follows:
JNIEXPORT jintArray JNICALL Java_my_opencv_Accesser_getSourceImage(JNIEnv * env,
jobject thiz) {
IplImage * pImage = cvLoadImage("/sdcard/Download/New.jpg");
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "cvLoadImage done");
if (pImage == 0) {
return NULL;
}
int len = pImage->width * pImage->height * 4;
jintArray rgbaData = env->NewIntArray(len);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME,
"New IntArray length is %d", len);
if (pImage->nChannels == 4) {
env->SetIntArrayRegion(rgbaData, 0, len, (jint*) pImage->imageData);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "nChannels : 4");
} else if (pImage->nChannels == 3) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "nChannels : 3");
IplImage* t = cvCreateImage(cvGetSize(pImage), 8, 4);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME,
"cvCreateImage success");
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME,
"pImage->height is %d", pImage->height);
for (int h = 0; h < pImage->height; h++) {
char* pt = t->imageData + h * t->widthStep;
char* pImg = pImage->imageData + h * pImage->widthStep;
for (int w = 0; w < pImage->width; w++) {
memcpy(pt, pImg, 3);
pt[3] = 255; //alpha
pt += 4;
pImg += 3;
}
}
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "For loop complete");
env->SetIntArrayRegion(rgbaData, 0, len, (jint*) t->imageData);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "setIntArrayRegion");
cvReleaseImage(&t);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Released &t");
} else {
}
cvReleaseImage(&pImage);
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Released &pImage");
return rgbaData;
}
And in my Java code I use the following:
int[] imageData = accesser.getSourceImage();
Bitmap bitmap = Bitmap.createBitmap(imageData, 0, width, width, height,
Config.ARGB_8888);
ImageView imageView = (ImageView) findViewById(R.id.imageView1);
imageView.setImageBitmap(bitmap);
Now my problem is that this code works perfectly for small sized images (50x50). But when the image size is increased (250x250) I get an error as:
09-19 00:21:07.332: I/dalvikvm-heap(29210): Grow heap (frag case) to 9.611MB for 921616-byte allocation
and then I get a SIGSEGV error:
09-19 00:21:07.352: A/libc(29210): Fatal signal 11 (SIGSEGV) at 0x513f1000 (code=1)
and then the program crashes. This happens only when I load relatively big images. I'm trying to build an OCR application and I need to load considerably BIG images. Please help.
PS: Using the log messages I found out that program crashes in SetIntArrayRegion() function.
--
int len = pImage->width * pImage->height * 4;
env->SetIntArrayRegion(rgbaData, 0, len, (jint*) pImage->imageData);
env->SetIntArrayRegion(rgbaData, 0, len/4, (jint*) pImage->imageData);