在MinGW主页很容易找到MinGW的下载页面。之后看到一大堆需要下载的包,头都大了。于是决定下载Automated MinGW Installer,让它在线下载安装MinGW及一些需要的组件。基本上只需要安装gcc组件就够了。
注册环境变量 D:\software\WinGW\mingw\bin; 在此目录之下要将mingw32-make.exe 重命名为make.exe
打开Eclipse,照例是HelloWorld。不过在开始写程序之前还是习惯性地先去看看配置选项。
General->Editors->Text Edtiors里把Show line numbers勾上了。按照编码规范每行代码是不应该超过80个字符的,所以勾上了Show print margin并将Print margin column设置成80。毕竟有一条参考线在编辑窗口中心里更有底。顺便把Insert spaces for tabs也勾上了,用空格代替制表符。后来编辑C++代码的时候发现缩进插入的仍然是制表符而不是空格。这才想起去C/C++->Code Style里去设置。
然后在C/C++->Editor->Syntax Coloring里去设置了一下语法高亮的格式。把所有粗体都取消了,把表示静态和常量的斜体也都换成了下划线。多年的习惯,看粗体和斜体就是不顺眼。
最后还在C/C++->New CDT project wizard里把MinGW设置成了默认的toolchain(选中MinGW GCC,点击Make tookchain preferred按钮),这样以后新建工程的时候就不用每次还要去点选一下了。
现在该新建HelloWorld项目了。从菜单File->New->C++ Project就打开了创建C++项目的向导。输入工程名并选好目录之后就可以Finish了,如下图。如果Next到下一页是选择Debug和Release两个配置。默认都是选中的。
工程建好后默认就把一些公用头文件的目录加在了Include设置里面,如图:
在工程属性里(Project->Properties)可以找到设置的地方,就在C/C++ General->Paths and symbos选项卡中,Inclues子卡里面。因为当前项目是C++ Project,所以Language选择GNU C++,右边的Include paths窗口就把包含的头文件目录都列出来了,如下图。如果项目需要包含其它头文件目录,也可以在这里添加。添加其它头文件目录的时候,通过GUI选择的路径是以绝对路径的方式添加进去的,也可以手工改成相对于当前工程目录的路径。
如果还需要设置链接的静态库,可以在Library paths里添加静态库所在的目录。但是,添加了静态库目录之后还需要添加需要链接的静态库,这就要在C/C++ Build->Settings里设置了。在这一设置的Tool settings选项卡中,找到MinGW C++ Linker->Libraries设置,这里可以添加需要链接的静态库(-l),也可以添加/修改这些静态库所在的目录(-L)。不过在这里添加静态库目录时使用相对路径似乎有点小问题,所以我一般就在上面提到的地方添加目录了。添加静态库的子窗口如下图:
项目属性中还有一个设置需要注意,就是C/C++ Build->Environment中的环境变量设置。主要是看有没有添加一个包含MinGW的bin目录的PATH变量。这个变量在创建工程的时候一般会自动添加。但如果没有正确设置PATH变量,编译的时候就会报错说不能运行g++或者gcc。如下图:
设置都差不多了,在项目中新添加一个名为main.cpp的Source File,输入测试代码:
#include
using namespce std;
int main(int argc, char* argv[]) {
cout << "Hello World!" << endl;
return 0;
}
然后右键编辑器内部,从菜单中选择Run As->Local C/C++ Application即可编译运行。如果需要调试,应该选择Debug As->Local C/C++ Application。不过每次使用Debug的时候都会报错,因为MinGW没有装gdb。以后有空再慢慢装吧。
—————————————————TDM-GCC———————————————————————-
第一步、下载TDM-GCC,安装,然后将bin目录放到环境变量当中
第二步、复制bin目录下面的mingw32-make.exe,重命名为make.exe,将x86_64-w64-xxxx.exe全部复制一份,将前面的x86_64-w64-去掉,然后重启eclipse
1.下载OpenCV-2.4.9-android-sdk
2.创建工程,编写Application.mk和Android.mk文件
APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI:= armeabi-v7a
Android.mk
LOCAL_PATH := $(call my-dir)
OPENCV_PATH:=/cygdrive/d/openCV/OpenCV-2.4.9-android-sdk
OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
include $(OPENCV_PATH)/sdk/native/jni/OpenCV.mk
LOCAL_C_INCLUDES+=$(OPENCV_PATH)/sdk/native/jni/include
LOCAL_MODULE:=BitmapMoti
LOCAL_SRC_FILES :=BitmapMoti.cpp
LOCAL_LDLIBS:=-lm -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
逐一解释下,OPENCV_INSTALL_MODULES:=on的意思是自动将依赖的OpenCV的so库拷贝到libs目录下,但很遗憾的是,这个命令只对OPENCV_CAMERA_MODULES有效。只有当OPENCV_CAMERA_MODULES:=on时,可以看到他会自动将里面的带camera的so拷贝至工程下的libs文件夹下。include D:\ProgramFile\OpenCV-2.4.9-android-sdk\sdk\native\jni\OpenCV.mk这句话比较关键,这是我安装OpenCV-2.4.9-android-sdk的地方,我将其安装到了D盘。而我的工作空间在E盘也是ok的。而不用像OpenCV2.3.1使用时,限制这个解压缩包的位置了。LOCAL_MODULE 是要生成的库的名字,LOCAL_SRC_FILES 是jni文件夹下的cpp文件,其中的src说明我的jni下还有个子文件夹名字是“src”,这块替换成自己的源码文件就ok了。
3.创建native方法:ImageUtils.java
public class ImageUtils {
static {
System.loadLibrary("Hello");
}
public static native void ImageBlur(Object bitmap);
public static Bitmap getDecodeBitmap(String path) {
if(!TextUtils.isEmpty(path) && new File(path).exists()){
BitmapFactory.Options options=new BitmapFactory.Options();
options.inPreferredConfig=Bitmap.Config.RGB_565;
return BitmapFactory.decodeFile(path, options);
}
return null;
}
}
4.在cmd窗口中进入src目录,然后键入:javah com.example.opencv02.ImageUtils便生成了.h的头文件,将头文件放到JNI目录当中编写本地文件,Hello.cpp
#include
#include
#include
#include
#include
#include
#include "com_example_opencv02_utils_ImageUtils.h"
#define LOG_TAG "fandong"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
using namespace cv;
JNIEXPORT void JNICALL Java_com_example_opencv02_utils_ImageUtils_ImageBlur(
JNIEnv * env, jclass clazz, jobject bitmap) {
AndroidBitmapInfo info;
void* address;
int ret;
//1.获取信息
if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("here 0 !");
return;
}
//2.锁定图像
if ((ret = AndroidBitmap_lockPixels(env, bitmap, &address)) < 0) {
LOGE("here 2 !");
return;
}
Mat source(info.height, info.width, CV_8UC2, (uchar*) address);
Mat dst;
cvtColor(source, dst, CV_BGR5652BGR);
//3.磨皮
fastNlMeansDenoisingColored(dst, dst);
/*4.均衡化
Mat planes[3]={Mat_(dst.rows,dst.cols),
Mat_(dst.rows,dst.cols),Mat_(dst.rows,dst.cols)};
split(dst,planes);
for(int i=0;i<3;i++){
equalizeHist(planes[i],planes[i]);
}
merge(planes,3,dst); */
cvtColor(dst, source, CV_BGR2BGR565);
LOGE("finish!!!!!!");
AndroidBitmap_unlockPixels(env, bitmap);
}
5.编写MainActivity.java
public class MainActivity extends Activity implements OnClickListener {
private Button bt, reset;
private ImageView iv;
private LinearLayout pb;
private Bitmap bitmap;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
showPB();
break;
case 1:
hidePB();
if (bitmap != null) {
iv.setImageBitmap(bitmap);
}
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt = (Button) this.findViewById(R.id.bt);
pb=(LinearLayout) this.findViewById(R.id.pb);
reset = (Button) this.findViewById(R.id.reset);
iv = (ImageView) this.findViewById(R.id.iv);
bt.setOnClickListener(this);
reset.setOnClickListener(this);
showOriginImage();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.reset:
showOriginImage();
break;
case R.id.bt:
showHandledImage();
break;
default:
break;
}
}
private void showHandledImage() {
new Thread() {
public void run() {
handler.sendEmptyMessage(0);
ImageUtils.ImageBlur(bitmap);
handler.sendEmptyMessage(1);
}
}.start();
}
private void showOriginImage() {
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/deng.jpg";
bitmap = ImageUtils.getDecodeBitmap(path);
iv.setImageBitmap(bitmap);
}
}
private void showPB(){
if(pb.getVisibility()==View.GONE){
pb.setVisibility(View.VISIBLE);
}
}
private void hidePB(){
if(pb.getVisibility()==View.VISIBLE){
pb.setVisibility(View.GONE);
}
}
}
6.运行
–>由于我们将该工程convert to C/C++ project,配置了编译指令${NDKROOT}/ndk-build
.cmd所以在运行的时候会自动生成so文件!**
1.下载opencv最新版本opencv2.4.9.exe 然后点击进行安装,选择安装路径,D:\software\
可以看到在D:\software\opencv2.4.9下面有两个文件夹build和sources
2.安装tdm-gcc-4.8.1-3.exe(也可以安装MinGW),安装完毕之后会在系统的环境变量path当中加入一下路径: D:\software\TDM-GCC-32\bin,(如果没有请自行添加)
2.1.安装CMake,首先下载CMake.exe并安装,
使用CMake,(cmake-gui.exe)选择源码路径:D:\software\opencv2.4.9\sources,选择编译路径:
D:\software\opencv2.4.9\build\x86\mingw(注意:如果PATH变量配置的有cygwin的bin文件夹路径的话,configure时会报错,两者会冲突,一定要先把cygwin的系统变量删除掉。)
4. 上一步正常的话就可以看到正在编译,左边会有进度显示。这个过程会持续半个小时左右.
5. 这个时候OpenCV2.4.9的库已经编译好了,下面只需要三步配置就能够正常调用了。注意,如果你前面装了Cygwin,那么如果你用相同的工作空间,cygwin配置的环境变量:C_INCLUDE_PATH CPLUS_INCLUDE_PATH会干扰你使用MinGW编译器。所以,最好重新建一个工作空间,并且重新建一个新的C++项目,然后按下面的配置三步就可以用OpenCV。记住一定是新的C++项目,如果你用以前C++项目配过OpenCV自带的mingw库但没成功,此刻编译好后无论你怎么配还是测试不通过。
6、在PATH系统变量里将路径:D:\software\opencv\build\x86\mymingw\bin 添加进去,这个目录下都是dll。设置完毕后保险起见,最好重启下电脑。然后再开Eclipse。如果Eclipse已经开着,最起码也要重启下。
8、新建一个工作空间Eclipse_MinGW_C,然后新建一个C++项目,选择MinGW做编译器。
9、左键选中项目,然后按alt+enter快捷键,选择C/C++ Build————-Settings———–Tool Settings,在GCC C++ Compiler的includes选项里添加目录:D:\software\opencv\build
\include (这个目录是opencv解压缩后默认的,跟编译无关)
10. 添加的libopencv_highgui249 都是在如下目录找的,记得不要带后缀:.dll.a。常用的有以下几个:
libopencv_calib3d249
libopencv_contrib249
libopencv_features2d249
libopencv_flann249
libopencv_gpu249
libopencv_imgproc249
libopencv_legacy249
libopencv_ml249
libopencv_core249
libopencv_highgui249
libopencv_nonfree249
libopencv_objdetect249
libopencv_ocl249
libopencv_photo249
libopencv_stitching249
libopencv_superres249
libopencv_video249
libopencv_videostab249
lib路径:D:\software\OpenCV2.4.9\opencv\build\x86\mingw\lib
如下图:
在Library search path(-L)里将路径:D:\software\opencv\build\x86\mymingw\lib 添加进去,这个路径下都是.a静态库。
11. 最后多说一句,如果像我一样不喜欢用VC的编译器,D:\software\OpenCV2.4.9\opencv\build\x86目录下的vc10、vc11、vc12完全可以删掉,丫的直接占了1.5G的空间。
1.新建好android工程
2.选择菜单栏File —>new —>convert to a c/c++ Project 在Candidates for conversion选择需要转换的工程,然后选择 C++ Project ,project type-Makefile project选择MinGW GCC— >Finish
3.将头文件的需找路径加入工程:在工程名上面点击右键— >C/C++ General –>Paths and Symbols—>Includes–>GNU C++ —>Add
4.在jni文件下面编写C++文件的时候就会有提示
5.注意:如果不想使用cygwin进行编译工程生成so文件,可以配置ndk-build.cmd
5.1 创建环境变量 NDKROOT=E:\android-ndk-r9d
5.2 在工程上面点击右键 – > properties– >C/C++ Build — >Builder Settings去掉use default build command 前面的箭头,然后在下面键入:
${NDKROOT}/ndk-build.cmd
5.3 上面的编译器默认是make,这也是为什么我们要将mingw32-make.exe改成 make.exe的原因,由于每次运行工程就会进行build,就会重新生成so文件,我们可以创建一个空的C++工程,编译成
opencv.exe ,然后放入${NDKROOT}
目录下面,不需要创建so的时候就将C/C++ builder当中的可执行文件改成 ${NDKROOT}/opencv
LOCAL_PATH := $(call my-dir)
OPENCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC
include D:/openCV/OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.cpp
LOCAL_LDLIBS += -lm -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)