JNI接口的实现中,有一段代码,功能是从一副图片中截取中间一部分,具体实现是这样的:
unsigned char *fun(unsigned char *data, int width, int height, int leftTopX, int leftTopY, int nWidth, int nheight)
//data, 图片内存首地址,width, height, 图片宽和高;
//leftTopX, leftTopY,截取区域左上角的点坐标
//nWidth, nHeight, 截取区域的宽和高
{
unsigned char *temp, *tempN;
unsigned char *pxl;
int size = nWidth * nHeight;
pxl = NULL;
if ((pxl = (unsigned char *)malloc(size * sizeof(unsigned char))) == NULL)
{
return NULL;
}
memset(readImg->pxl, 0x00, sizeof(size * sizeof(unsigned char)));
temp = data + width * leftTopY + leftTopX;
tempN = pxl;
for (i = 0; i < nHeight; i++)
{
__android_log_print(ANDROID_LOG_INFO, "[hello-jni.c]", "i is %d", i);
memcpy(tempN, temp, nWidth);
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_0");
temp += width;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_1");
tempN += nWidth;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_2");
} return pxl;
}上面是这部分完整的代码,这个应用在大部分android手机上都没有问题,但在阿里云手机上就会出错。出现的问题是这样的,
假设nHeight是200,那要循环200次,可是从log上看,每次出错都是循环没有运行完,而且是memcpy这一句出错。请大侠帮忙看看,问题怎么解决?
unsigned char *fun(unsigned char *data, int width, int height, int leftTopX, int leftTopY, int nWidth, int nheight)
//data, 图片内存首地址,width, height, 图片宽和高;
//leftTopX, leftTopY,截取区域左上角的点坐标
//nWidth, nHeight, 截取区域的宽和高
{
unsigned char *temp, *tempN;
unsigned char *pxl;
int size = nWidth * nHeight;
pxl = NULL;
if ((pxl = (unsigned char *)malloc(size * sizeof(unsigned char))) == NULL)
{
return NULL;
}
memset(readImg->pxl, 0x00, sizeof(size * sizeof(unsigned char)));
temp = data + width * leftTopY + leftTopX;
tempN = pxl;
for (i = 0; i < nHeight; i++)
{
__android_log_print(ANDROID_LOG_INFO, "[hello-jni.c]", "i is %d", i);
memcpy(tempN, temp, nWidth);
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_0");
temp += width;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_1");
tempN += nWidth;
__android_log_write(ANDROID_LOG_INFO, "[hello-jni.c]", "123456789_2");
} return pxl;
}上面是这部分完整的代码,这个应用在大部分android手机上都没有问题,但在阿里云手机上就会出错。出现的问题是这样的,
假设nHeight是200,那要循环200次,可是从log上看,每次出错都是循环没有运行完,而且是memcpy这一句出错。请大侠帮忙看看,问题怎么解决?
下面是log里的内容:01-02 04:36:42.870: W/System.err(3364): width:800
01-02 04:36:42.870: I/[hello-jni.c](3364): data is 407591e8
01-02 04:36:42.870: I/[hello-jni.c](3364): size is 67200
01-02 04:36:42.870: I/[hello-jni.c](3364): pxl is 40040008
01-02 04:36:42.870: I/[hello-jni.c](3364): width is 800,
01-02 04:36:42.870: I/[hello-jni.c](3364): height is 448,
01-02 04:36:42.870: I/[hello-jni.c](3364): nWidth is 200,
01-02 04:36:42.870: I/[hello-jni.c](3364): nHeight is 336,
01-02 04:36:42.870: I/[hello-jni.c](3364): leftTopX is 300,
01-02 04:36:42.870: I/[hello-jni.c](3364): leftTopY is 56,
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 0
01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764214, tempN is 40040008
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 1
01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764534, tempN is 400400d0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 2
01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 40764854, tempN is 40040198
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
……
……
……
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 213
01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 4078dbb4, tempN is 4004a670
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 214
01-02 04:36:42.870: I/[hello-jni.c](3364): temp is 4078ded4, tempN is 4004a738
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_0
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_1
01-02 04:36:42.870: I/[hello-jni.c](3364): 123456789_2
01-02 04:36:42.870: I/[hello-jni.c](3364): i is 215
01-02 04:36:42.900: V/NvOmxCamera(19858): First preview frame displayed
01-02 04:36:42.900: V/NvOmxCamera(19858): ReleaseWakeLock
01-02 04:36:42.900: V/NvOmxCamera(19858): NvOmxCamera::NvOmxCameraGraphEventHandler --输入data地址为0x407591e8;pxl初始化为0x40040008;
第一次循环:
temp是0x40764214, 0x40764214 == 0x407591e8(data) + 800(width) * 56(leftTopY ) + 300(leftTopX),
tempN是0x40040008,0x40040008 == 0x40040008;
第二次循环:
temp: 0x40764534 - 0x40764214 == 800(width);
tempN: 0x400400d0 - 0x40040008 == 200(nWidth);从这些参数里都看不出问题。循环到215次时就出错了,memcpy()那一句后面的log都没有打印出来。
1,memcpy()函数,参数size值大的情况下,会出错,其后的log打印不出来。
比如copy一幅图片的内存,一次copy整幅图的话,就出错了,
分成一行一行copy的话,就可以运行下去。
2,接问题1,一幅图一行一行copy,需要循环height次,
这里我的height是448,一般循环到200多次的时候会挂掉。
这些都 是从log上看出来的。
01-02 04:36:42.870: I/[hello-jni.c](3364): width is 800,
01-02 04:36:42.870: I/[hello-jni.c](3364): height is 448,
为什么你的width > height ? 本身就是这样的值?
再把其他正常的手机中的值打印出来对比一下呢
//readImg->pxl=px1要吗?
tempN = pxl;
for (i = 0; i < nHeight; i++)
//i<nHeight-leftTopY吧
有可能是log太多的缘故,未必是问题
我现在发现这个问题,我的接口是这样的:
unsigned char *fun(unsigned char *data, int width, int height, int leftTopX, int leftTopY, int nWidth, int nheight);
按正常思路,data所指向空间的大小应该和width、height匹配。
我最初想的是空间大小应该等于width*height。
但实际中发现不是这样的。我这试了三款手机,A和B上运行正常,C上运行错误,就是前面提到的那些问题。
A机的三个值:空间大小614800,width854, height480;
B机的三个值:空间大小514800,width720, height480;
C机的三个值:空间大小115200,width800, height448;
这些值都是Java调用端得到的。分析这三组值,发现
614800 > 854 * 480; 614800 / 2 == 854 * 480;
514800 > 720 * 480; 514800 / 2 == 720 * 480;
115200 < 800 * 448;现在想不通的是,为什么空间大小不等于width*height,这些可都是8位灰度图啊。另外大家在android上开发相机图片应用时,获取的图片数据有没有发现这一问题呢?
他们帮忙取到了data空间的大小,发现这个大小比width*height小,这个是问题的原因,
当时取width和height是手机说明的分辨率大小,后来用另一种方法取到了一组新的width、height,这样两部分就吻合了,再传进来就OK,
至于用什么办法取到的width和height,我也不知道了,