Android Studio上NDK编程步骤与演示
来源:互联网 发布:淘宝网店服装模特招聘 编辑:程序博客网 时间:2024/05/21 10:25
Android Studio上NDK编程步骤与演示
在AndroidStudio(AS)上搞NDK编程首先要下载与安装NDK,搞好了这步之后。只需要以下几步配置与操作就可以轻松开始NDK编程与运行。
新建一个纯Android项目(不包含C++支持)
在新项目中创建一个新Java文件为BitmapProcessor.java, 定义两个本地方法,代码实现如下:
package com.gloomyfish.ndkdemo;import android.graphics.Bitmap;/** * Created by jia20003 on 2017/5/18. */public class BitmapProcessor { static { System.loadLibrary("BitmapProcessor"); } public native void gray(Bitmap bm); public native void inverse(Bitmap bm);}
编译含有本地方法的Java文件和产生.h的C++文件
首先新建一个bat脚本文件javahrun.bat然后写入如下内容
set JAVA_HOME="C:\Program Files\Java\jdk1.8.0_92"set path=%JAVA_HOME%\bin;%path%set classpath=.;%classpath%;%JAVA_HOME%\lib;C:\Users\Administrator\AppData\Local\Android\sdk\platforms\android-24\android.jarjavah com.gloomyfish.ndkdemo.BitmapProcessor
首先用javac BitmapProcessor.java这句替换脚本文件中的最后一句,然后保存该文件到项目所在的目录下app\src\main\java\com\gloomyfish\ndkdemo位置之后,通过cmd命令行执行javahrun.bat即可。
成功执行的话会生成一个.class文件在相同目录下面
然后退到目录app\src\main\java\下面,同时把bat文件修改为之前的脚本,直接执行就会生成.h的头文件,在app\src\main目录下新建jni与jniLIB两个目录文件夹之后,把.h头文件copy到jni文件夹中,这个时候在AS看到的目录结构应该如下:
新建一个C++源文件命名为BitmapProcessor.cpp, 实现头文件中定义与声明的两个本地方法即可,注意这个可以在VS2015中完成。设置一下头文件即可,如果你不知道该include多少个或者哪个,直接把目录%disk_dir%Android\android-ndk-r13b\platforms\android-24\arch-arm\usr\include下的全部添加到VS2015的include配置中即可。这样写完程序,确保没有C++的语法错误,然后copy到AS中。
编译含有C++的NDK项目
首先要设置一下NDK的路径, 右键项目打开Module Settings
然后设置好NDK路径即可。
其次,在app对应的build.gradle文件添加如下一段脚本
最后在gradle.properties文件中添加上一句话
android.useDeprecatedNdk=true
如果不加的话,编译就会又错误出现。
然后【build】->【clean build】, 【rebuild】
就编译好啦!
使用so库与编写java相关代码
首先把编译生成的app\build\intermediates\ndk\debug\lib下面的文件全部copy到之前建好的jniLIB里面即可。然后完成Java部分代码编写,实现用户交互与UI响应操作。
这里我通过JNI实现了在C++层对Bitmap对象的灰度化操作与颜色取反操作然后返回结果。运行效果如下:
相关Java与C++代码实现
MainActivity.java
package com.gloomyfish.ndkdemo;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button grayBtn = (Button)this.findViewById(R.id.gray_btn); Button invertBtn = (Button)this.findViewById(R.id.invert_btn); grayBtn.setOnClickListener(this); invertBtn.setOnClickListener(this); } @Override public void onClick(View v) { int id = v.getId(); switch (id) { case R.id.gray_btn: convert2Gray(); break; case R.id.invert_btn: invertImage(); break; default: break; } } private void invertImage() { Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.test); BitmapProcessor processor = new BitmapProcessor(); processor.inverse(bm); ImageView iv = (ImageView)this.findViewById(R.id.imageView_001); iv.setImageBitmap(bm); } private void convert2Gray() { Bitmap bm = BitmapFactory.decodeResource(this.getResources(), R.drawable.test); BitmapProcessor processor = new BitmapProcessor(); processor.gray(bm); ImageView iv = (ImageView)this.findViewById(R.id.imageView_001); iv.setImageBitmap(bm); }}
BitmapProcessor.cpp
//// Created by gloomy fish on 2017/5/18.//#include<android/bitmap.h>#include<android/log.h>#include<com_gloomyfish_ndkdemo_BitmapProcessor.h>#ifndef eprintf#define eprintf(...) __android_log_print(ANDROID_LOG_ERROR,"@",__VA_ARGS__)#endif#define RGBA_A(p) (((p) & 0xFF000000) >> 24)#define RGBA_R(p) (((p) & 0x00FF0000) >> 16)#define RGBA_G(p) (((p) & 0x0000FF00) >> 8)#define RGBA_B(p) ((p) & 0x000000FF)#define MAKE_RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))JNIEXPORT void JNICALL Java_com_gloomyfish_ndkdemo_BitmapProcessor_gray (JNIEnv *env, jobject clazz, jobject bmpObj) { AndroidBitmapInfo bmpInfo={0}; if(AndroidBitmap_getInfo(env,bmpObj,&bmpInfo)<0) { eprintf("invalid bitmap\n"); return; } void * dataFromBmp = NULL; int res = AndroidBitmap_lockPixels(env, bmpObj, &dataFromBmp); if(dataFromBmp == NULL) { eprintf("could not retrieve pixels from bitmap\n"); return; } eprintf("Effect: %dx%d, %d\n", bmpInfo.width, bmpInfo.height, bmpInfo.format); int x = 0; int y = 0; int width = bmpInfo.width; int height = bmpInfo.height; for(y=0; y<height; y++) { for(x=0; x<width; x++) { int a = 0, r = 0, g = 0, b = 0; void *pixel = NULL; pixel = ((uint32_t *)dataFromBmp) + y * width + x; uint32_t v = *(uint32_t *)pixel; a = RGBA_A(v); r = RGBA_R(v); g = RGBA_G(v); b = RGBA_B(v); // Grayscale int gray = (r * 38 + g * 75 + b * 15) >> 7; // Write the pixel back *((uint32_t *)pixel) = MAKE_RGBA(gray, gray, gray, a); } } AndroidBitmap_unlockPixels(env, bmpObj);}JNIEXPORT void JNICALL Java_com_gloomyfish_ndkdemo_BitmapProcessor_inverse (JNIEnv *env, jobject clazz, jobject bmpObj) {AndroidBitmapInfo bmpInfo={0}; if(AndroidBitmap_getInfo(env,bmpObj,&bmpInfo)<0) { eprintf("invalid bitmap\n"); return; } void * dataFromBmp = NULL; int res = AndroidBitmap_lockPixels(env, bmpObj, &dataFromBmp); if(dataFromBmp == NULL) { eprintf("could not retrieve pixels from bitmap\n"); return; } eprintf("Effect: %dx%d, %d\n", bmpInfo.width, bmpInfo.height, bmpInfo.format); int x = 0; int y = 0; int width = bmpInfo.width; int height = bmpInfo.height; for(y=0; y<height; y++) { for(x=0; x<width; x++) { int a = 0, r = 0, g = 0, b = 0; void *pixel = NULL; pixel = ((uint32_t *)dataFromBmp) + y * width + x; uint32_t v = *(uint32_t *)pixel; a = RGBA_A(v); r = RGBA_R(v); g = RGBA_G(v); b = RGBA_B(v); // 取反操作 r = 255 - r; g = 255 - g; b = 255 - b; // Write the pixel back *((uint32_t *)pixel) = MAKE_RGBA(r, g, b, a); } } AndroidBitmap_unlockPixels(env, bmpObj);}
PS:
我之所有把图像处理相关的都整到C++这一层来,是因为Android Studio 上用Java干这个事情真TMD太慢了,唯一C++才是唯一出路,想做AR或者图像处理与视频分析必须要学会此技能!
- Android Studio上NDK编程步骤与演示
- android studio NDK编程
- Android Studio Ndk 编程
- Android Studio NDK 编程
- Android Studio Ndk 编程
- Android Studio上进行NDK编程之Hello world
- Android Studio上进行NDK编程之Hello world
- Android Studio 与 NDK
- android studio ndk编程 配置
- Android Studio 使用NDK编程
- Android Studio下的ndk开发步骤
- Android Studio上实现一个最简单的ndk项目的步骤
- [Android]Android Studio上的NDK开发
- Android Studio JNI NDK编程(一)
- Android Studio NDK开发--JNI编程
- Android Studio NDK,JNI编程入门
- Android Studio实现NDK编程学习笔记
- android studio NDK编程(一)
- python之selenium调用js(execute_script)
- You Are the One(区间DP)
- RAII(Resource Acquisition Is Initialization:资源获取即初始化)
- spirng cloud学习笔记-Zuul
- MySql---集中练习MySQL的CRUD-->select查询
- Android Studio上NDK编程步骤与演示
- 第1章 Oracle的简介
- git add -A 和 git add . 的区别
- redis安装(centos单机版)
- 求数组中的逆序对
- dojo.require()
- bzoj 3669 魔法森林
- 前端JQuery强大的物理模板引擎
- oracle常用命令--更新/修改表数据之update命令