完成了 NDK(Native Development Kit)和 OpenCV 安裝和設置後,便可以測試 OpenCV 的 C++ 程式,現在 Android Studio 中已經可以調用 OpenCV 的C/C++。
Android Studio 的 NDK + OpenCV + CPP 測試程式 |
- 操作系統:Windows 7 64-bit 版本
- 開發環境:Android Studio 4.0.1 版本
- Gradle 版本:6.1.1
- 手機測試版本:API 19
- 原程式:C:\Development\Development_Android\Android_Project\NDK
- 程式:C:\Development\Development_Android\Android_Project\NDK
- NDK 版本:NDK 21.0.6113669 版本 Android
app / java / MainActivity.java:
package bugworkshop.blogspot.ndk;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle; import android.widget.TextView; import org.opencv.android.OpenCVLoader; import android.util.Log;
import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.View; import android.widget.Button; import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); }
private Button btn_1; private Button btn_2; private ImageView imageView; private Bitmap bitmap;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
// Example of a call to a native method TextView tv = findViewById(R.id.sample_text); tv.setText(stringFromJNI()); Toast.makeText(MainActivity.this, stringFromJNI(),Toast.LENGTH_LONG).show();
if (OpenCVLoader.initDebug()) { Log.i("CV", "Load OpenCV Library Successful."); tv.setText("Load OpenCV Library Successfully."); } else { Log.i("CV", "Load OpenCV Library Failed."); tv.setText("Load OpenCV Library Failed.");; }
btn_1 = (Button)findViewById(R.id.button_1); imageView = (ImageView)findViewById(R.id.image); bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.face01); btn_1.setOnClickListener(this);
btn_2 = (Button)findViewById(R.id.button_2); btn_2.setOnClickListener(this);
}
public void showImage(){ bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.face01); imageView.setImageBitmap(bitmap); }
public void gray(){ int w = bitmap.getWidth(); int h = bitmap.getHeight(); int[] piexls = new int[w*h]; bitmap.getPixels(piexls,0,w,0,0,w,h); int[] resultData =Bitmap2Grey(piexls,w,h); Bitmap resultImage = Bitmap.createBitmap(w,h, Bitmap.Config.ARGB_8888); resultImage.setPixels(resultData,0,w,0,0,w,h); imageView.setImageBitmap(resultImage); }
@Override public void onClick(View view){ switch(view.getId()){ case R.id.button_1:showImage();break; case R.id.button_2:gray();break; } }
/** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native int[] Bitmap2Grey(int[] pixels,int w,int h);
/** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI();
@Override public void onResume(){ super.onResume(); } } |
2﹒native-lib.cpp 是 C++ 程式。
app / cpp / native-lib.cpp:
#include<opencv2/opencv.hpp>
using namespace cv; using namespace std;
extern "C" JNIEXPORT jintArray JNICALL Java_bugworkshop_blogspot_ndk_MainActivity_Bitmap2Grey( JNIEnv *env, jobject /* this */,jintArray buf,jint w,jint h) { jint *cbuf; jboolean ptfalse = false; //讀取 int 陣列並轉為 Mat 類型 cbuf = env->GetIntArrayElements(buf, &ptfalse); if(cbuf == NULL){ return 0; }
Mat imgData(h, w, CV_8UC4, (unsigned char*)cbuf); // 注意,Android 的 Bitmap 是 ARGB 四通道,而不是 RGB 三通道 cvtColor(imgData,imgData,CV_BGRA2GRAY); cvtColor(imgData,imgData,CV_GRAY2BGRA);
int size=w * h; jintArray result = env->NewIntArray(size); env->SetIntArrayRegion(result, 0, size, (jint*)imgData.data); env->ReleaseIntArrayElements(buf, cbuf, 0); return result; }
extern "C" JNIEXPORT jstring JNICALL Java_bugworkshop_blogspot_ndk_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } |
3﹒介面內容佈局。
app / res / layout / active_main.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="vertical">
<TextView android:id="@+id/sample_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
<ImageView android:id="@+id/image" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" app:srcCompat="@drawable/face01" /> </LinearLayout>
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:orientation="horizontal">
<Button android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Gray" />
<Button android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="Color" /> </LinearLayout>
</LinearLayout> |
沒有留言:
張貼留言