1.压力计
每隔一秒产生一个随机数,就设定为压力值,然后在ProgressBar上显示出来。一般来讲用java也能做,但这次用jni来做
先定义一个操作类
public class ProgressBarOperation {
static {
System.loadLibrary("Pressure");
}
public native void startMonitor();
public native void stopMonitor();
}
这个类决定每隔一秒是否产生随机数
MainAcitivity关键代码
//button响应事件
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_start) {
new Thread(new Runnable() {
@Override
public void run() {
operation.startMonitor();
}
}).start();
} else if (v.getId() == R.id.btn_stop) {
operation.stopMonitor();
}
}
//这个函数和下个函数是为了测试调用一般函数和静态函数的区别
public void setPressure(int pressure) {
Log.e("pressure", "" + pressure);
handler.obtainMessage(0x001, pressure, 0).sendToTarget();
}
public static void set(int pressure) {
Log.e("pressure", "" + pressure);
handler.obtainMessage(0x001, pressure, 0).sendToTarget();
}
private static Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what == 0x001){
progressBar.setProgress(msg.arg1);
}
};
};
private static Context context;
public static void init(int pressure){
((MainActivity) context).setPressure(pressure);
}
cpp文件代码如下
//生成随机数
int getPressure() {
return rand() % 100;
}
int flag = JNI_TRUE;
JNIEXPORT void JNICALL Java_com_example_pressuretest_ProgressBarOperation_startMonitor(
JNIEnv *env, jobject obj) {
while (flag) {
sleep(1);
//静态方法
//jclass clazz = env->FindClass("com/example/pressuretest/MainActivity");
//jmethodID methodId = env->GetStaticMethodID(clazz, "set", "(I)V");
//env->CallStaticVoidMethod(clazz, methodId, getPressure());
//非静态方法
jclass clazz = env->FindClass("com/example/pressuretest/MainActivity");
jmethodID methodId = env->GetStaticMethodID(clazz, "init", "(I)V");
env->CallStaticVoidMethod(clazz, methodId, getPressure());
//我的这种做法是将非静态方法强制转成静态方法来实现的,不科学,具体的讨论在
//http://ask.csdn.net/questions/325670
}
}
JNIEXPORT void JNICALL Java_com_example_pressuretest_ProgressBarOperation_stopMonitor(
JNIEnv *env, jobject obj) {
flag = JNI_FALSE;
}
2.图像二值化
先定义一个二值化的工具类
public class Binary {
static {
System.loadLibrary("binary");
}
public static native int[] binaryImage(int[] buff, int width, int height,
int threshold);
}
MainActivity里面这样调用
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
textView.setText("阈值是:" + thresHold);
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
// binaryImage会把pix替换掉
int[] result_pix = Binary.binaryImage(pix, w, h, thresHold);
result.setPixels(result_pix, 0, w, 0, 0, w, h);
imageView.setImageBitmap(result);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
thresHold = progress;
textView.setText("阈值是:" + progress);
}
});
cpp文件代码如下
JNIEXPORT jintArray JNICALL Java_com_example_binaryimage_Binary_binaryImage(
JNIEnv *env, jclass clz, jintArray buffer, jint width, jint height,
jint threshold) {
jint *cbuf = env->GetIntArrayElements(buffer, JNI_FALSE);
if (cbuf == NULL) {
return 0; /* exception occurred */
}
jint alpha = 0xFF << 24;
for (jint i = 0; i < height; i++) {
for (jint j = 0; j < width; j++) {
// 获得像素的颜色
jint color = cbuf[width * i + j];
jint red = ((color & 0x00FF0000) >> 16);
jint green = ((color & 0x0000FF00) >> 8);
jint blue = color & 0x000000FF;
color = (red + green + blue) / 3;
//__android_log_print(ANDROID_LOG_ERROR, "TAG", "pix=%d", color);
if (color <= threshold) {
color = 0;
} else {
color = 255;
}
color = alpha | (color << 16) | (color << 8) | color;
cbuf[width * i + j] = color;
}
}
jint size = width * height;
jintArray result = env->NewIntArray(size);
env->SetIntArrayRegion(result, 0, size, cbuf);
env->ReleaseIntArrayElements(buffer, cbuf, 0);
return result;
}