windows下eclipse_adt_sdk_ndk_opencv环境搭建

本文讲解windows下eclipse+adt+sdk+ndk+opencv环境搭建,并成功运行图片处理功能。


全部工具下载

http://pan.baidu.com/s/1skr6rDF


     1、安装java开发环境jdk-8u65-windows-x64.exe

在系统变量中添加:

JAVA_HOME        D:\A_Program Files\Java\jdk1.8.0_65

CLASSPATH          .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

Path                      %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;


2、安装eclipse

目标路径不要有空格


3、安装sdkinstaller_r24.4.1-windows.exe(翻墙)

注意路径不要有空格,然后进入安装的目录打开SDK Manager.exe


勾选如下内容安装:

 

4、安装插件adt,需要翻墙

4、安装插件adt,需要翻墙

打开eclipsehelp->install new software

输入https://dl-ssl.google.com/android/eclipse/ 全选出现的插件,下一步,安装


5、配置sdkndk目录

解压android-ndk64-r10b-windows-x86_64.zip,路径不要有空格,打开eclipse

Window->Preferences


 



        6、安装bluestack模拟器

   Installer_native2.0.2.5624.1451269209.exe

       7、创建android工程

           创建android工程,先看看能否正常生成apk在模拟器上运行

File->New->Other


 


 


 

 

 


 


finish 把废弃的ActionBarActivity改成Activity,再导入Activity包


 

代码如下

</pre><pre name="code" class="java">package com.example.tp002;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
 
public class MainActivity extends Activity {
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
 
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
 
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//Handle action bar item clicks here. The action bar will
//automatically handle clicks on the Home/Up button, so long
//as you specify a parent activity in AndroidManifest.xml.
intid = item.getItemId();
if(id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

运行配置Run->Run configurations

 

 

Apply->close

启动bluestacks,如果分辨率太大可以在注册表中修改

修改完后

Run->build_app

会部署到模拟器上自动运行

 

        8C/C++ so库的编译

    右键工程名,AndroidTools-> add nativesupport

    jni目录下面打开cpp文件,发现jni.h找不到

右键工程properties->c/c++General->Paths and Symbols

Add->File system添加ndkjni头文件目录

D:\C_Code\Android\android-ndk-r10b\platforms\android-L\arch-arm64\usr\include

配置native编译

 

Run ->build_native

会在libs armeabi目录下生成libtp002.so

这个so什么代码都没有,下面增加个helloworld

代码如下,注意函数名字的结构是

Java_包名(._代替)_工程名_调用本接口的activty_本函数名

#include<jni.h>
 
#ifndef _Included_jni_HelloWorld
#define _Included_jni_HelloWorld
#ifdef __cplusplus
extern "C"{
#endif
 
JNIEXPORT jstring JNICALL Java_com_example_tp002_MainActivity_HelloWorld
  (JNIEnv * env, jobject obj)
{
return env->NewStringUTF("Hello From CPP");
}
 
#ifdef __cplusplus
}
#endif
#endif

再次编译so,通过。


java中增加调用代码

首先是加载so库和声明本地函数

static{
        System.loadLibrary("tp002");
    }
public native StringHelloWorld();

为了观察效果,需要获取TextView控件,在原有activity_main.xml中的TextView中增加Id

 <TextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="@string/hello_world"
       android:id="@+id/tvHello"/>

然后java中增加操作TextView的代码

protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
 
TextView myText = (TextView)findViewById(R.id.tvHello);
myText.setText(HelloWorld());
}

运行效果:

 

 

完整代码如下

CPP

#include<jni.h>
 
#ifndef _Included_jni_HelloWorld
#define _Included_jni_HelloWorld
#ifdef __cplusplus
extern "C"{
#endif
 
JNIEXPORT jstring JNICALL Java_com_example_tp002_MainActivity_HelloWorld
  (JNIEnv * env, jobject obj)
{
return env->NewStringUTF("Hello From CPP");
}
 
#ifdef __cplusplus
}
#endif
#endif

JAVA

 

package com.example.tp002;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
 
public class MainActivity extends Activity {
   
static{
        System.loadLibrary("tp002");
    }
public native String HelloWorld();
 
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
 
TextView myText = (TextView)findViewById(R.id.tvHello);
myText.setText(HelloWorld());
}
}

到这里已经打通了jni调用

下面增加opencv


9、增加opencv例程

解压OpenCV-2.4.11-android-sdk.zip,路径不要有空格

首先修改jni目录下的mk,新建一个Application.mk内容为

APP_ABI := armeabi-v7a
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-9

Android.mk内容为

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC
include D:\C_Code\Android\OpenCV-android-sdk\sdk\native\jni\OpenCV.mk
LOCAL_LDLIBS    += -lm -llog -landroid

LOCAL_MODULE    := tp002
LOCAL_SRC_FILES := tp002.cpp

include $(BUILD_SHARED_LIBRARY)


CPP例程内容:

#include <jni.h>
#include <opencv2/opencv.hpp>

using namespace cv;

extern "C" {
JNIEXPORT jintArray JNICALL Java_com_example_tp002_MainActivity_ImgFun(
    JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT jintArray JNICALL Java_com_example_tp002_MainActivity_ImgFun(
    JNIEnv* env, jobject obj, jintArray buf, int w, int h) {
	jint *cbuf;
	    cbuf = env->GetIntArrayElements(buf, NULL);
	    if(cbuf == NULL){
	        return 0;
	    }

	    Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf);

	    uchar* ptr = imgData.ptr(0);
	    for(int i = 0; i < w*h; i ++){
	        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, cbuf);
	    env->ReleaseIntArrayElements(buf, cbuf, 0);
	    return result;
}

}


到这里就已经可以编译通过了,但是eclipse还是提示opencv的头文件和类型无法解析,应该是eclipse的错误检查没办法从mk中读取opencv的头文件,那我们把头文件路径添加到eclipse的环境变量中,工程右键,properties

 

同样,为了观察效果,我们在activity_main.xml中增加一个buttonImageView控件,去掉前面用到的TextView控件

    <Button 
        android:id="@+id/btnProcessPic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/proc_pic"/>
    
    <ImageView
        android:id="@+id/ivAndroid"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/meinv"/>


增加图片资源,名字和上面控件用到的一致


 

strings.xml中增加button显示的字符串

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">tp002</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="proc_pic">duang~</string>

</resources>



Java调用代码:

package com.example.tp002;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {
    
	static{
        System.loadLibrary("tp002");
    }
//	public native String HelloWorld();
    public native int[] ImgFun(int[] buf, int w, int h);
    private ImageView ivAndroid;
    private Button btnProcessPic;
    
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
        btnProcessPic = (Button) findViewById(R.id.btnProcessPic);
        ivAndroid = (ImageView) findViewById(R.id.ivAndroid);
        
        btnProcessPic.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {				
				long current = System.currentTimeMillis();
		        @SuppressWarnings("deprecation")
				Bitmap img1 = ((BitmapDrawable) getResources().getDrawable(R.drawable.meinv)).getBitmap();
		        int w = img1.getWidth(), h = img1.getHeight();
		        int[] pix = new int[w * h];
		        img1.getPixels(pix, 0, w, 0, 0, w, h);
		        int[] resultInt = ImgFun(pix, w, h);
		        Bitmap resultImg = Bitmap.createBitmap(w, h, Config.ARGB_8888);
		        resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);
		        ivAndroid.setImageBitmap(resultImg);
			}

		});
	}
}



运行效果



点击按钮

至此,全部完成!脖子好酸。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值