这两天在android上面做一个图片格式转换的程序,这个程序代码很少,VisualStudio上面用openCV来做主要就下面几行代码:

IplImage* img = cvLoadImage(szOriPic);cvSaveImage( szNewPic , img);cvReleaseImage( &img );

但是做androidndk+openCV开发,最大的困难就是配置环境,因为自己不懂makefile以及linux下开发的基本知识,所以很多androiddevguide的东西都不是很懂,只能一步步照着别人的例子来做,中间遇到了很多问题,终于做出来了,现在把整个过程记录下来,算是对这几天的一个总结.

-环境

winXP+cygwin

android-ndk-r4-crystax(支持c++标准的ndk,普通ndk不能编译openCV代码)

OpenCV-2.3.1-beta1-android-bin或者从cygwin"svncheckout http://android-opencv.googlecode.com/svn/trunk/"openCVcheckout出来然 后按照http://blog.csdn.net/hellogv/article/details/6094127这篇博文中所说 的步骤重新编译openCV(这个需要很长时间)


-配置环境

主要的配置步骤参见http://blog.csdn.net/hellogv/article/details/6094127,需要注意的地方有:

*cygwinandroid-ndk-r4-crystax放到C盘下(其他地方也可以,最好路径中不要带空格),windows的环境变量Path中添加C:\cygwin\bin;C:\android-ndk-r4-windows-crystax-4\android-ndk-r4-crystax,这样在cygwin中就可以直接用"ndk-build"(普通ndk"ndk-build"编译openCV的代码会出错,这个错误犯了好几次才真正明白).

-开发步骤

1.Eclipse中新建androidproject:

Projectname:ImageSample

Applicationname:ImageSample

Packagename:com.sample.ImageSample

CreateActivity:ImageSample

TargetName:Android2.2

MinSDKVersion:8


2.在该项目的目录下建立jni文件夹(ImageSample/jni),jni目录下建立 Android.mk文件以及ImageConverter.cc,两个文件的内容如下:

ImageConverter.cc

#include <jni.h>#include <cstdlib>   #include <stdexcept>   #include <string> #include <opencv2/core/core.hpp>   #include <opencv2/features2d/features2d.hpp>   #include <opencv2/highgui/highgui.hpp>   #include <opencv2/imgproc/imgproc.hpp>   #include <opencv2/calib3d/calib3d.hpp>   #include <opencv2/imgproc/imgproc_c.h>  extern "C"{ JNIEXPORT jstring JNICALL Java_com_example_pictrans_PicTrans_DoConvert  (JNIEnv *env, jobject obj){       
        try
        {
            IplImage* imgIn = cvLoadImage("/sdcard/testimage.bmp");
            if (!imgIn) return env->NewStringUTF("Error");            std::string filePath="/sdcard/result_pic.png";       jstring filePath1=env->NewStringUTF(filePath.c_str());       const char * resultpath=env->GetStringUTFChars(filePath1, 0);        cvSaveImage(resultpath,imgIn);             cvReleaseImage( &imgIn );        }        catch(...)        {            return env->NewStringUTF("exception");        }        return env->NewStringUTF("ok");}


---------------------------------------------------------------------

Android.mk

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)include /cygdrive/c/OpenCV-2.3.1-beta1-android-bin/OpenCV-2.3.1/share/OpenCV/OpenCV.mkLOCAL_LDLIBS +=  -llog -ldlLOCAL_CPP_EXTENSION := ccLOCAL_MODULE    := ImageConverterLOCAL_SRC_FILES := ImageConverter.ccinclude $(BUILD_SHARED_LIBRARY)


上面是基于OpenCV-2.3.1-beta1-android-bin,如果是自己重新编译好的openCV,Android.mk文件中内容是:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)#OPENCV_ROOT must be defined.ifndef OPENCV_ROOT$(warning Please define OPENCV_ROOT to point to the root folder of opencv, try ndk-build OPENCV_ROOT=../../opencv)OPENCV_ROOT=/cygdrive/C/android-opencv/opencv$(warning Defaulting to OPENCV_ROOT=$(OPENCV_ROOT))endif#define OPENCV_INCLUDESinclude $(OPENCV_ROOT)/includes.mk#define OPENCV_LIBSinclude $(OPENCV_ROOT)/libs.mk LOCAL_LDLIBS += $(OPENCV_LIBS) -llog    LOCAL_C_INCLUDES +=  $(OPENCV_INCLUDES) LOCAL_STATIC_LIBRARIES := calib3d features2d objdetect imgproc \     video  highgui ml legacy core libopencv_lapack flann \    libzlib libpng libjpeg libjasperLOCAL_CPP_EXTENSION := ccLOCAL_MODULE    := ImageConverterLOCAL_SRC_FILES := ImageConverter.ccinclude $(BUILD_SHARED_LIBRARY)


我这个工程建在openCVsample目录下,请根据自己的实际项目目录更改实际的openCV的引用位置

---------------------------------------------------------------------

3.将OpenCV-2.3.1\libs\armeabi下和 OpenCV-2.3.1\share\OpenCV\3rdparty\libs\armeabi(我用的这个版本的 openCV中的.a文件有一部分名字多了"lib",需要去掉多余的"lib",如果是自己编译的 openCV,好像不用3rdparty\libs\armeabi下的文件).a文件复制到该工程的 \obj\local\armeabi目录下,这个目录需要新建,cygwin中进入到该工程目录下, 后执行"ndk-build",生成libs\armeabi\libImageConverter.so(如果用的是 自己编译的openCV,则需要用"ndk-buildOPENCV_ROOT=../../opencv" 不 是"ndk-build",因为Android.mk中需要用到OPENCV_ROOT)

4.在Eclipse打开ImageSample.java,在类ImageSample中添加:

public native String DoConvert();       static {
                  System.loadLibrary("ImageConverter");
              }


声明需要用到的native函数名称,并且android程序运行时可以加载此库

5.onCreate函数内容如下:

@Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        TextView tv = new TextView(this);        tv.setText(DoConvert());        setContentView(tv);    }


6.打开AndroidManifest.xml文件在Applicationtag上面添加下面这条语句:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 

这条语句让该程序有权限访问sd卡上的文件,如果不加,DoConvert函数就不能加载 和生成图片.

7.Eclipse中打开一个模拟器(需要有sd卡设置),打开androidFile Explorer,上传一个名为"testimage.bmp"的图片到mnt/sdcard,运行 程序,当程序界面出现"ok",查看sdcard下是否多了一个result_pic.png 的文件,如果出现,则说明转换成功.可以将此文件拖到电脑上查看图片(刚拖下 来的时候文件不知被FileExplorer占用还是被其他程序占用,不能阅览,此时 可以复制一份该图片,预览复制的那一份即可).

更多相关文章

  1. App安全(一) Android防止升级过程被劫持和换包
  2. 深入了解android平台的jni---编译ffmpeg源码
  3. 在Eclipse中用javadoc给android工程库文件生成API说明文档
  4. android实现上传本地图片到网络功能
  5. 【Android(安卓)开发教程】保存到外部存储设备(SD卡)
  6. 用kotlin写了一些android常用的一些工具类
  7. android完整权限
  8. Ubuntu 12.04 64位编译cm-10.2 总结
  9. Android应用程序安装与Launcher启动机制

随机推荐

  1. android 实现代码关机
  2. Android(安卓)EditText 设置键盘右下角显
  3. Android之设备ID(Device ID)
  4. Android 经典小技巧总结
  5. eclipse中安装android ADT插件及无法下载
  6. 移动网络设置
  7. Android获取当前网络状态和获取当前设备
  8. 【Android】Android6.0发送短信Demo
  9. Android(安卓)网络--我是怎么做的: Volle
  10. android判断当前网络状态,eth wifi pppoe