将图片的每个像素元素转变为int值,存入到一个int数组中,将该数组传入到C++层去处理
下面以一个图片灰度化的例子来说明:
Java代码:
//将资源调入
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.luffy);
//得到bitmap类型的宽度,用于得到像素
width = bitmap.getWidth();
//得到bitmap类型的高度
height = bitmap.getHeight();
//定义一个像素数组,用来存储每一个像素
pixArr = new int[width*height];
//将bitmap的每个像素颜色转为int值,从指定的偏移位置(offset),指定的位置(x,y)截取指定的宽高 (width,height ),存入pixels
// void getPixels (int[] pixels, int offset,int stride,int x,int y,int width, int height)
bitmap.getPixels(pixArr,0,width,0,0,width,height);
//本地定义的gray函数(在C++部分实现的图像灰度化函数,处理后的像素信息存储在pirArr之中)
gray(pixArr,width,height);
//定义一个新的Bitmap对象,用来复现处理后的图像
Bitmap newBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.RGB_565);
newBitmap.setPixels(pixArr,0,width,0,0,width,height);
传递数组其实是传递一个堆内存的数组首地址的引用过去,所以实际操作的是同一块内存,
当调用完方法,不需要返回值,实际上参数内容已经改变
本地gray函数定义:
public native int[] gray(int [] pix,int w,int h);
C++部分处理:
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_example_bymyself_MainActivity_gray(JNIEnv *env, jobject thiz, jintArray pix_, jint w,
jint h) {
jint *pix = env->GetIntArrayElements(pix_, NULL);
if (pix == NULL) {
return 0;
}
//将c++图片转成Opencv图片
Mat imgData(h, w, CV_8UC4, (unsigned char *) pix);
uchar* ptr = imgData.ptr(0);
for(int i = 0; i < w*h; i ++){
//计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B
//对于一个int四字节,其彩色值存储方式为:BGRA
int grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);
ptr[4*i+1] = grayScale;
ptr[4*i+2] = grayScale;
ptr[4*i+0] = grayScale;
}
int size = w * h;
//创建一个新的数组,用来返回使用
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, pix);
//ReleaseIntArrayElements这个函数是将处理完的副本复制回基本函数
env->ReleaseIntArrayElements(pix_, pix, 0);
return result;
}