In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
Editor to share with you the JNI project in AndroidStudio and quote OpenCV example analysis, I believe that most people do not know much about it, so share this article for your reference, I hope you will learn a lot after reading this article, let's go to know it!
1. Create Project 1.1: download the SDK of OpenCV
First, go to the official website to download OpenCV's Android package.
Where the so file is located: sdk-> native-> libsc++ Code: sdk-> native-> jni-> include-> opencv21.2: create a project of Android Native C++
The project structure is as follows
1.3: run the first project
The result is as follows, with a line in the middle: "Hello from C++"
2.JNI initial project analysis 2.1:MainActivity analysis
Native-lib is loaded using the System.loadLibrary method in a static code block
The native method stringFromJNI () returns a String and sets it to TextView.
-> [src/main/java/com/toly1994/rec/MainActivity.java]-public class MainActivity extends AppCompatActivity {static {System.loadLibrary ("native-lib");} @ Override protected 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.2:native-lib.cpp analysis
Introduced jni and string header files, a Java_com_toly1994_rec_MainActivity_stringFromJNI function
A sring variable is defined in the function body, and a string is created through the env pointer and returns
# 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# specifies the minimum version of cmake cmake_minimum_required (VERSION 3.4.1) # generate the shared library native-libadd_library (native-lib SHARED native-lib.cpp) using the native-lib.cpp file # find the log library alias log-libfind_library (log-lib log) # set the library target_link_libraries (native-lib ${log-lib}) 3. Integrated OpenCV3.1: import and reference of libraries
Copy the required libraries and so packages into the project, and the configuration of CMakeLists.txt
# specify minimum version of cmake cmake_minimum_required (VERSION 3.4.1) include_directories (include) # introduce folder # compile header file # define global my_source_path variable file (GLOB my_source_path ${CMAKE_SOURCE_DIR} / * .cpp ${CMAKE_SOURCE_DIR} / * .c) add_library (tolyCV SHARED ${my_source_path}) # add dynamic link library add_library (lib_opencv SHARED IMPORTED) set_ Target_properties (lib_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR} /.. / jniLibs/$ {ANDROID_ABI} / libopencv_java4.so) # find the log library alias log-libfind_library (log-lib log) in ndk # find the jnigraphics library alias jnigraphics-lib# jnigraphics in ndk find_library (jnigraphics-lib jnigraphics) # set the library target_link_libraries (tolyCV) that target needs to link to Lib_opencv ${jnigraphics-lib} ${log-lib}) 3. 2: bug that almost ruined my ndk career
Dlopen failed: library "libc++_shared.so" not found
This bug got stuck on my way to ndk like a nightmare, so that I almost gave up. Five days later, I finally came up with the solution:
-> [app/build.gradle]-android {defaultConfig {externalNativeBuild {cppFlags "" arguments "- DANDROID_STL=c++_shared" / using c++_shared.so}} 3.3: create a utility class for bitmap
The Bitmap class of Android cannot be directly manipulated in C++, so it needs to be converted into pixel matrix processing, which is first written as a header file here.
For # include's floating red, you need 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 transform matrix * @ param env JNI environment * @ param bitmap Bitmap object * @ param mat picture matrix * @ param needPremultiplyAlpha is preceded by transparency * / void bitmap2Mat (JNIEnv * env, jobject bitmap, Mat * mat, bool needPremultiplyAlpha = false) / * Matrix to Bitmap * @ param env JNI environment * @ param mat Picture Matrix * @ param bitmap Bitmap object * @ param needPremultiplyAlpha is preceded by transparency * / void mat2Bitmap (JNIEnv * env, Mat mat, jobject bitmap, bool needPremultiplyAlpha = false) / * * create Bitmap * @ param env JNI environment * @ param src matrix * @ param config Bitmap configuration * @ return Bitmap object * / jobject createBitmap (JNIEnv * env, Mat src, jobject config);} # endif / / REC_UTILS_H4.OpenCV to achieve grayscale images
4.1: here are the specific implementations of the three methods
Bitmap2Mat obtains the pixel matrix through bitmap and puts it into mat, so that mat can be operated in C++.
Mat2Bitmap, on the contrary, places the pixel information of the matrix into it by putting the mat matrix
CreateBitmap acquires the object through reflection and the createBitmap method in Android, and places information through mat2Bitmap.
# include "bitmap_utils.h" void bitmap2Mat (JNIEnv * env, jobject bitmap, Mat * mat, bool needPremultiplyAlpha) {AndroidBitmapInfo info; void * pixels = 0; Mat & dst = * mat; / / get information and some assertions CV_Assert (AndroidBitmap_getInfo (env, bitmap, & info) > = 0) / / get Bitmap information CV_Assert (info.format = = ANDROID_BITMAP_FORMAT_RGBA_8888// picture format RGBA_8888 or 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) / / get Bitmap information CV_Assert (info.format = = ANDROID_BITMAP_FORMAT_RGBA_8888// picture format RGBA_8888 or RGB_565 | | info.format = = ANDROID_BITMAP_FORMAT_RGB_565); CV_Assert (mat.dims==2&&info.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"); / / Class name jmethodID mid=env- > GetStaticMethodID (java_bitmap_class, "createBitmap", / / get method "(IILandroid/graphics/Bitmap$Config;) Landroid/graphics/Bitmap;"); jobject bitmap=env- > CallStaticObjectMethod (java_bitmap_class,mid,src.cols,src.rows,config); mat2Bitmap (env,src,bitmap, false) Return bitmap;} 4.2: actions in MainActivity:
The layout is very simple, do not post, an iv_photo ImageView.
When clicking, call a native method of opBitmap to make the image grayed out.
Public class MainActivity extends AppCompatActivity {static {System.loadLibrary ("tolyCV");} @ Override protected 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.3
The pixel information of the picture is grayed out in dstMat, and then dstMat is used to create a Bitmap object, so the logic is smooth.
-> [cpp/native-lib.cpp]-# include # include "bitmap_utils.h" extern "C" JNIEXPORT 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) / / the pixel information of the picture is grayed out in dstMat return createBitmap (env,dstMat,argb8888); / / create a Bitmap object using dstMat} these are all the contents of this article entitled "JNI Project in AndroidStudio and sample Analysis of quoting OpenCV". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.