第一模板网站上的模板怎么下载,电子商务平台经营者通过交易规则,关键词排名点击,慈利网站开发一把利刃#xff0c;用不好#xff0c;会伤到你遍体鳞伤。用得好#xff0c;便为你披荆斩棘#xff0c;所向披靡。好与不好之间#xff0c;便是历练。几经波折#xff0c;终于跌跌撞撞,集成了OpenCV,并实现了灰度图片#xff0c;自此一扇新的大门已经打开。至此我手中已…一把利刃用不好会伤到你遍体鳞伤。用得好便为你披荆斩棘所向披靡。好与不好之间便是历练。几经波折终于跌跌撞撞,集成了OpenCV,并实现了灰度图片自此一扇新的大门已经打开。至此我手中已经基本集齐了所需的技能碎片。本文你包括:[1].OpenCV在AndroidStudio中的集成[2].第一个JNI项目的解析[3].JNI中对于Android中的Bitmap类的使用[4].一个灰度的例子开启OpenCV的世界1、创建项目1.1下载OpenCV的SDKso文件所在: sdk - native - libsc的代码 : sdk - native - jni - include - opencv21.2创建一个Android Native c的项目项目结构如下1.3运行第一个项目结果如下在中间显示了一行:Hello from C2.JNI初始项目分析2.1MainActivity分析在静态代码块中使用System.loadLibrary方法加载了native-libnative方法stringFromJNI()返回一个String并设置到了TextView上----[src/main/java/com/toly1994/rec/MainActivity.java]----public class MainActivity extends AppCompatActivity {static {System.loadLibrary(native-lib);}Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv findViewById(R.id.sample_text);tv.setText(stringFromJNI());}/*** A native method that is implemented by the native-lib native library,* which is packaged with this application.*/public native String stringFromJNI();}2.2native-lib.cpp分析引入了jni和string头文件一个Java_com_toly1994_rec_MainActivity_stringFromJNI函数函数体中定义了一个sring变量并通过env指针创建了一个字符串并返回#include #include extern C JNIEXPORT jstring JNICALLJava_com_toly1994_rec_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */) {std::string hello Hello from C;return env-NewStringUTF(hello.c_str());}2.3:CMakeLists.txt#指定 cmake 的最小版本cmake_minimum_required(VERSION 3.4.1)# 使用native-lib.cpp文件生成共享库native-libadd_library(native-lib SHARED native-lib.cpp )# 在ndk中查找log库 取别名log-libfind_library(log-lib log )#设置 target 需要链接的库target_link_libraries(native-lib ${log-lib} )3.集成OpenCV3.1库的导入及引用将需要的库以及so包拷贝到项目中以及CMakeLists.txt的配置#指定 cmake 的最小版本cmake_minimum_required(VERSION 3.4.1)include_directories(include)#引入文件夹#编译头文件#定义全局 my_source_path 变量file(GLOB my_source_path ${CMAKE_SOURCE_DIR}/*.cpp ${CMAKE_SOURCE_DIR}/*.c)add_library(tolyCV SHARED ${my_source_path})#添加动态链接库add_library(lib_opencv SHARED IMPORTED)set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libopencv_java4.so)# 在ndk中查找log库 取别名log-libfind_library(log-lib log)# 在ndk中查找jnigraphics库 取别名jnigraphics-lib# jnigraphics包含图形操作的库find_library(jnigraphics-lib jnigraphics)#设置 target 需要链接的库target_link_libraries(tolyCVlib_opencv${jnigraphics-lib}${log-lib})3.2几乎断送我ndk生涯的bugdlopen failed: library libc_shared.so not found这个bug如噩梦般卡在我ndk前行的路上以致我几乎放弃五天后终得解法----[app/build.gradle]----android {defaultConfig {externalNativeBuild {cmake {cppFlags arguments -DANDROID_STLc_shared//使用c_shared.so}}}3.3创建bitmap的工具类C中无法直接操作Android的Bitmap类所以需要转化为像素矩阵处理,这里先写成头文件。关于#include android/xxxxx的飘红需要 build -- Refresh Linked C Projects----[cpp/bitmap_utils.h]----#ifndef REC_UTILS_H#define REC_UTILS_H#include #include using namespace cv;//Matextern C {/*** Bitmap 转矩阵* param env JNI环境* param bitmap Bitmap对象* param mat 图片矩阵* param needPremultiplyAlpha 是否前乘透明度*/void bitmap2Mat(JNIEnv *env, jobject bitmap, Mat *mat, bool needPremultiplyAlpha false);/*** 矩阵转Bitmap* param env JNI环境* param mat 图片矩阵* param bitmap Bitmap对象* param needPremultiplyAlpha 是否前乘透明度*/void mat2Bitmap(JNIEnv *env, Mat mat, jobject bitmap, bool needPremultiplyAlpha false);/**** 创建Bitmap* param env JNI环境* param src 矩阵* param config Bitmap配置* return Bitmap对象*/jobject createBitmap(JNIEnv *env, Mat src, jobject config);}#endif //REC_UTILS_H4.OpenCV实现灰度图片4.1下面是三个方法的具体实现bitmap2Mat 通过bitmap获取像素矩阵放入mat中这样mat就可以在C中操作mat2Bitmap 与上面相反通过将mat矩阵将矩阵的像素信息置入其中createBitmap 通过反射获取Android中的createBitmap方法获取对象在通过mat2Bitmap置入信息。#include bitmap_utils.hvoid bitmap2Mat(JNIEnv *env, jobject bitmap, Mat *mat, bool needPremultiplyAlpha) {AndroidBitmapInfo info;void *pixels 0;Mat dst *mat;//获取信息和一些断言CV_Assert(AndroidBitmap_getInfo(env, bitmap, info) 0);//获取Bitmap信息CV_Assert(info.format ANDROID_BITMAP_FORMAT_RGBA_8888//图片格式RGBA_8888 或RGB_565|| info.format ANDROID_BITMAP_FORMAT_RGB_565);CV_Assert(AndroidBitmap_lockPixels(env, bitmap, pixels) 0);CV_Assert(pixels);dst.create(info.height, info.width, CV_8UC4);if (info.format ANDROID_BITMAP_FORMAT_RGBA_8888) {Mat tmp(info.height, info.width, CV_8UC4, pixels);if (needPremultiplyAlpha) {cvtColor(tmp, dst, COLOR_mRGBA2RGBA);} else {tmp.copyTo(dst);}} else {Mat tmp(info.height, info.width, CV_8UC2, pixels);cvtColor(tmp, dst, COLOR_BGR5652RGBA);}AndroidBitmap_unlockPixels(env, bitmap);}void mat2Bitmap(JNIEnv *env, Mat mat, jobject bitmap,bool needPremultiplyAlpha) {AndroidBitmapInfo info;void *pixels 0;CV_Assert(AndroidBitmap_getInfo(env, bitmap, info) 0);//获取Bitmap信息CV_Assert(info.format ANDROID_BITMAP_FORMAT_RGBA_8888//图片格式RGBA_8888 或RGB_565|| info.format ANDROID_BITMAP_FORMAT_RGB_565);CV_Assert(mat.dims2info.height(uint32_t)mat.rows info.width(uint32_t)mat.cols);CV_Assert(mat.type()CV_8UC1||mat.type()CV_8UC3||mat.type()CV_8UC4);CV_Assert(AndroidBitmap_lockPixels(env, bitmap, pixels) 0);CV_Assert(pixels);if (info.format ANDROID_BITMAP_FORMAT_RGBA_8888) {Mat tmp(info.height, info.width, CV_8UC4, pixels);switch (mat.type()){case CV_8UC1:cvtColor(mat,tmp,COLOR_GRAY2RGBA);break;case CV_8UC3:cvtColor(mat,tmp,COLOR_RGB2RGBA);break;case CV_8UC4:cvtColor(mat,tmp,COLOR_RGBA2mRGBA);if (needPremultiplyAlpha) {cvtColor(mat, tmp, COLOR_RGBA2mRGBA);} else {mat.copyTo(tmp);}break;default:break;}} else {Mat tmp(info.height, info.width, CV_8UC2, pixels);switch (mat.type()){case CV_8UC1:cvtColor(mat,tmp,COLOR_GRAY2BGR565);break;case CV_8UC3:cvtColor(mat,tmp,COLOR_RGB2BGR565);break;case CV_8UC4:cvtColor(mat,tmp,COLOR_RGBA2BGR565);break;default:break;}}AndroidBitmap_unlockPixels(env, bitmap);}jobject createBitmap(JNIEnv *env, Mat src, jobject config){jclass java_bitmap_class(jclass)env-FindClass(android/graphics/Bitmap);//类名jmethodID midenv-GetStaticMethodID(java_bitmap_class,createBitmap,//获取方法(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;);jobject bitmapenv-CallStaticObjectMethod(java_bitmap_class,mid,src.cols,src.rows,config);mat2Bitmap(env,src,bitmap, false);return bitmap;}4.2在MainActivity中的操作:布局很简单就不贴了一个iv_photo的ImageView。在点击时调用一个opBitmap的native方法使得图片灰度化。public class MainActivity extends AppCompatActivity {static {System.loadLibrary(tolyCV);}Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ImageView iv findViewById(R.id.iv_photo);iv.setOnClickListener(v - {tv.setText(stringFromJNI());Bitmap bitmap BitmapFactory.decodeResource(getResources(), R.mipmap.wy_300x200);iv.setImageBitmap(opBitmap(bitmap,Bitmap.Config.ARGB_8888));});}public native Bitmap opBitmap(Bitmap bitmap, Bitmap.Config argb8888);}4.3C文件中的处理将图片的像素信息灰度化盛放在dstMat再使用dstMat创建一个Bitmap对象至此一个逻辑就通畅了----[cpp/native-lib.cpp]---#include #include #include #include bitmap_utils.hextern CJNIEXPORT jobject JNICALLJava_com_toly1994_rec_MainActivity_opBitmap(JNIEnv *env, jobject instance, jobject bitmap,jobject argb8888) {Mat srcMat;Mat dstMat;bitmap2Mat(env, bitmap, srcMat);cvtColor(srcMat, dstMat, CV_BGR2GRAY);//将图片的像素信息灰度化盛放在dstMatreturn createBitmap(env,dstMat,argb8888);//使用dstMat创建一个Bitmap对象}至此本篇结束。简单必有简单的成本复杂必有复杂的价值。