您的位置:首页 > 移动开发 > Android开发

通过jni实现图像处理

2016-07-02 20:23 597 查看
参考多位前辈的文章,经过自己动手操作,终于实现了调用jni实现图像处理的功能。

大体上,我将操作过程分为7步:

1、从assets目录下读图片文件;

2、通过java的解码把图片文件解码成 Bitmap;

3、通过 getPixels 获取 bitmap 中的图片数据;

4、通过 jni 接口把获取的byte[] 数组传到c++边;

5、c++边通过env的函数获取对应的byteArray的c指针;

6、对过该指针操作image的数据,做灰度化处理;

7、将c++处理后的数据,回放到bimap中,进行显示。

下面分步来介绍:

1、从assets目录下读图片文件;

String fileName = "laoshan.jpg";// 图片文件名字
InputStream in = getResources().getAssets().open(fileName);
int length = in.available();
byte[] buffer = new byte[length];
in.read(buffer);//读取到buffer中


2、通过java的解码把图片文件解码成 Bitmap;

BitmapFactory.Options opts = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length, opts);


3、通过 getPixels 获取 Bitmap 中的图片数据;

int sizeBitmap=bitmap.getByteCount();//获取bitmap的大小 = w*h*4
byte[] byteArray=new byte[sizeBitmap];//开辟数组,存放像素内容
ByteBuffer dst=ByteBuffer.wrap(byteArray);
bitmap.copyPixelsToBuffer(dst); //拷贝像素值


4、通过 jni 接口把获取的byte[] 数组传到c++边;

ProcessResult processResult = JniClient.processByteArray(byteArray, w, h);


5、c++边通过env的函数获取对应的byteArray的c指针;

char * buf_pic = (char *)env->GetByteArrayElements( data, 0); // 获取int数组元素


6、对过该指针操作image的数据,做灰度化处理;

我们通过一个函数来实现:

imgToGrayARGB(buf_pic, w, h);


在说明这个函数的内容之前,先简单说下Android中Bitmap的数据格式:

如果未特别设置,那么Bitmap的数据格式是 ARGB_8888,这是一种色彩的存储方法:里面A代表Alpha,R表示red,G表示green,B表示blue。“8888”是说明每个色彩使用8位来表示,也就是1字节。就是一个像素需要4字节来存储,分别是透明度、红、绿、蓝。

imgToGrayARGB()函数中主要的工作,是对每个像素获取rgb值,然后计算灰度值,设置。

red = (unsigned char)buf[i+0]; // 获得red值
green = (unsigned char)buf[i+1]; // 获得green值
blue = (unsigned char)buf[i+2]; // 获得blue值
color = (red * 38 + green * 75 + blue * 15) >> 7; // 灰度算法(16位运算下7位精度)
red = green = blue = color; // 以灰度值来设置rgb
buf[i+0]=red;
buf[i+1]=green;
buf[i+2]=blue;
buf[i+3]=0xff;//设置为不透明


7、将c++处理后的数据,回放到bimap中,进行显示;

dst.rewind();//将buffer的读写位置归0
bitmap.copyPixelsFromBuffer(dst);//设置bitmap的像素值
iv_pic.setImageBitmap(bitmap);//显示图片


demo下载地址:

http://download.csdn.net/detail/lintax/9565857
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息