Anroidピクチャフォーマット変換プログラム(winXP+cygwin+opencv+ndk)

6143 ワード

この2,3日androidの上で1つのピクチャーのフォーマットの変換のプログラムをして、このプログラムのコードは少なくて、Visual Studioの上でopenCVで主に下のいくつかの行のコードをします:
IplImage* img = cvLoadImage(szOriPic);
cvSaveImage( szNewPic , img);
cvReleaseImage( &img );

しかしandroid ndk+openCVの開発をするには、最大の困難は環境の配置であり、自分がmakefileやlinuxの下で開発した基本的な知識を理解していないため、多くのandroid dev guideのものがよく分からず、一歩一歩他の人の例に従って行うしかなく、途中で多くの問題に遭遇し、ついに完成し、今全体の過程を記録して、この数日の総括と言える.
-環境
winXP+cygwin
android-ndk-r 4-crystax(c++標準のndkをサポートし、通常のndkではopenCVコードをコンパイルできません)
OpenCV-2.3.1-beta 1-android-binまたはcygwinから"svn checkouthttp://android-opencv.googlecode.com/svn/trunk/「OpenCVチェックアウトしてhttp://blog.csdn.net/hellogv/article/details/6094127このブログで述べた手順でopenCVを再コンパイルします(これは長い時間がかかります)
-環境の構成
主な構成手順については、http://blog.csdn.net/hellogv/article/details/6094127、注意すべき点は次のとおりです.
*cygwinとandroid-ndk-r 4-crystaxをCディスクの下に置き(他の場所でもいいですが、パスにスペースを入れないほうがいいです)、windowsの環境変数PathにC:cygwinbinを追加します.C:android-ndk-r 4-windows-crystax-4android-ndk-r 4-crystax、これでcygwinで直接「ndk-build」を使うことができます(普通のndkの「ndk-build」でopenCVのコードをコンパイルするとエラーが発生し、このエラーは何度も犯してやっと本当に分かります).
-開発手順
1.Eclipseでandroidプロジェクトを新規作成:
Project name:ImageSample
Application name:ImageSample
Package name:com.sample.ImageSample
Create Activity:ImageSample
Target Name:Android 2.2
Min SDK Version:8
2.プロジェクトのディレクトリの下にjniフォルダ(つまりImageSample/jni)を作成し、jniディレクトリの下にAndroidを作成する.mkファイルおよびImageConverter.cc、2つのファイルの内容は以下の通りです.
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.mk
LOCAL_LDLIBS +=  -llog -ldl
LOCAL_CPP_EXTENSION := cc
LOCAL_MODULE    := ImageConverter
LOCAL_SRC_FILES := ImageConverter.cc
include $(BUILD_SHARED_LIBRARY)

OpenCV-2.3.1-beta 1-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_INCLUDES
include $(OPENCV_ROOT)/includes.mk
#define OPENCV_LIBS
include $(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 libjasper
LOCAL_CPP_EXTENSION := cc
LOCAL_MODULE    := ImageConverter
LOCAL_SRC_FILES := ImageConverter.cc
include $(BUILD_SHARED_LIBRARY)

このプロジェクトはopenCVのsampleディレクトリの下に建てられています.自分の実際のプロジェクトディレクトリに基づいて実際のopenCVの参照位置を変更してください.
---------------------------------------------------------------------
3.OpenCV-2.3.1libsarmeabiの下とOpenCV-2.3.1shareOpenCV3 rdpartylibsarmeabi(私が使っているこのバージョンのopenCVの中の.aファイルの一部の名前が「lib」より多くなっているので、余分な「lib」を削除する必要があります.自分でコンパイルしたopenCVであれば、3 rdpartylibsarmeabiの下のファイルは使わないようです).aファイルをプロジェクトのobjlocalarmeabiディレクトリにコピーします.このディレクトリは新規作成する必要があります.cygwinでプロジェクトディレクトリの下に入り、「ndk-build」を実行してlibsarmeabilibImageConverterを生成します.soライブラリ(「ndk-build」ではなく「ndk-build OPENCV_ROOT=..//../opencv」が必要です.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ファイルは、アプリケーションタグに次の文を追加します.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  

この文はプログラムにsdカードのファイルにアクセスする権限を与え、追加しないとDoConvert関数はピクチャをロードして生成できない.
  7.Eclipseでシミュレータを開き(sdカード設定が必要)、androidのFile Explorerを開き、「testimage.bmp」という画像をmnt/sdcardの下にアップロードし、プログラムを実行し、プログラムインタフェースに「ok」が表示された場合、sdcardの下にresultが1つ増えたかどうかを確認します.pic.pngのファイルは、現れると変換に成功することを示す.このファイルをパソコンにドラッグして画像を見ることができます(ドラッグしたばかりの頃はファイルがFile Explorerに占有されているか他のプログラムに占有されているか分からず、閲覧できませんでしたが、この場合はその画像をコピーして、コピーしたものをプレビューすればいいです).