一、项目结构
jni相关的单独放在一个文件夹内,包括
- st_stereo.h,main.cpp,这个是要进行编译的文件
- lib下的libSTdisp.so,libStereoblur.so,前面要编译的文件所引用的库文件
-
android.mk和Application.mk
二、android.mk中相关设置
注意点有:
1.前面两个库的引用基本是固定写法,结尾写成
include $(PREBUILT_SHARED_LIBRARY)
2.第三个库为main.cpp,是我们要编译的库,它引用其他.so库的时候,用
LOCAL_SHARED_LIBRARIES := CLEAR_VARS
LOCAL_SHARED_LIBRARIES += STdisp
LOCAL_SHARED_LIBRARIES += Stereoblur
3.新建项目默认是没有ndk环境的,需要右键项目AndroidTools里启用NDK环境,如果没有这一步,项目是没有obj文件夹的,之后ndk-build也不会正常编译
Android.mk
LOCAL_PATH := $(call my-dir)
LOCAL_PREBUILT_DIR := prebuilt
include $(CLEAR_VARS)
LOCAL_MODULE := Stereoblur
LOCAL_MODULE_PATH := ./
LOCAL_SRC_FILES := $(LOCAL_PREBUILT_DIR)/lib/$(TARGET_ARCH_ABI)/libStereoblur.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := STdisp
LOCAL_MODULE_PATH := ./
LOCAL_SRC_FILES := $(LOCAL_PREBUILT_DIR)/lib/$(TARGET_ARCH_ABI)/libSTdisp.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := jniSTDualCamPreview
#LOCAL_C_INCLUDES += $(LOCAL_PATH)/include $(LOCAL_PATH)/$(LOCAL_PREBUILT_DIR)/include
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := CLEAR_VARS
LOCAL_SHARED_LIBRARIES += STdisp
LOCAL_SHARED_LIBRARIES += Stereoblur
LOCAL_LDLIBS += -lstdc++ -llog -ldl -lGLESv2 -lm -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
#APP_ABI := armeabi-v7a arm64-v8a
APP_ABI := armeabi-v7a
#APP_ABI := armeabi-v7a x86 arm64-v8a
APP_PLATFORM := android-18
#忽略warning,防止编译不通过
APP_CFLAGS += -Wno-error=format-security
三、main.cpp文件
这就是一个普通的.cpp文件,所以很多写法要遵守cpp的格式来写,比如头文件的引入,方法的重复定义报的错,都需要一修改
#include
#include
#include
#include "prebuilt/include/st_stereo.h"
#include "license.h"
#include
//#ifndef _Included_stereo_engine
#define _Included_stereo_engine
#ifndef _Included_com_example_nodspdualcampreview_JNIUtils
#define _Included_com_example_nodspdualcampreview_JNIUtils
#if defined (__cplusplus)
extern "C" {
#endif
void readYUVFile(char *fileName, int image_width, int image_height,
unsigned char *dataPointer) {
int yuv_len = image_width * (image_height + image_height / 2);
FILE *file = fopen(fileName, "rb");
fread(dataPointer, 1, yuv_len, file);
fclose(file);
}
int main(int argc, char *argv[]) {
initLicense(license);
void *handle = NULL;
stStereoSize_t inLeft_size;
stStereoSize_t inRight_size;
stStereoSize_t out_size;
inLeft_size.width = 1440;
inLeft_size.height = 1080;
inLeft_size.width_stride = 1536;
inLeft_size.height_stride = 1088;
inRight_size.width = 1440;
inRight_size.height = 1080;
inRight_size.width_stride = 1536;
inRight_size.height_stride = 1088;
out_size.width = 1440;
out_size.height = 1080;
out_size.width_stride = 1536;
out_size.height_stride = 1088;
handle = initStereoEngine(inLeft_size, inRight_size, out_size);
if (handle == NULL) {
return -1;
}
stCalibParam_t Param;
FILE *pFile = fopen("/sdcard/preview/OTP_buffer.bin", "rb");
const int length = 512;
unsigned char buffer[length];
fread(buffer, 1, length, pFile);
fclose(pFile);
Param.OTP_buffer = buffer;
Param.OTP_size = length;
int calib_result = 0;
calib_result = initCalibrateParam(handle, Param);
if (calib_result != 0) {
return -1;
}
int left_length = inLeft_size.width_stride * inLeft_size.height_stride
* 1.5;
int right_length = inRight_size.width_stride * inRight_size.height_stride
* 1.5;
int out_length = out_size.width_stride * out_size.height_stride * 1.5;
unsigned char *left_image = new unsigned char[left_length];
unsigned char *right_image = new unsigned char[right_length];
unsigned char *out_image = new unsigned char[out_length];
stStereoEnv_t cam_info;
int blur_state[1];
readYUVFile("/sdcard/preview/left.yuv", inLeft_size.width_stride,
inLeft_size.height_stride, left_image);
readYUVFile("/sdcard/preview/right.yuv", inRight_size.width_stride,
inRight_size.height_stride, right_image);
FILE *para = fopen("/sdcard/preview/camInfo.bin", "rb");
fread(&cam_info, sizeof(stStereoEnv_t), 1, para);
fclose(para);
for (int i = 0; i < 100; i++) {
int stereoBlur_result = 0;
stereoBlur_result = stereoBlur(handle, left_image, right_image,
out_image, 0, 0, 1, cam_info, blur_state);
if (stereoBlur_result != 0) {
return -1;
}
}
FILE *out_file = fopen("/sdcard/preview/out.yuv", "w");
if (out_file == NULL) {
} else {
fwrite(out_image, sizeof(unsigned char), 1536 * 1088 * 3 / 2, out_file);
}
delete[] left_image;
delete[] right_image;
delete[] out_image;
fclose(out_file);
releaseStereoEngine(handle);
return 0;
}
//自己的jni方法,上面必须引用
JNIEXPORT jstring JNICALL Java_com_example_nodspdualcampreview_JNIUtils_getString(
JNIEnv *env, jobject obj) {
return env->NewStringUTF("Hello World shit!");
}
JNIEXPORT void JNICALL Java_com_example_nodspdualcampreview_JNIUtils_preview(
JNIEnv *env, jobject obj) {
//调用上面设定的方法
main(1,NULL);
}
#if defined (__cplusplus)
}
#endif
#endif
四、将main.cpp编译成.so文件
这一步比较简单,命令行进入jni文件夹下,运行ndk-build即可,期间可能会遇到各种问题,百度解决即可,此时的主要问题一般是cpp文件编译的问题
1.遇到一个编译waning问题
在Application.mk中加入这个即可
忽略warning,防止编译不通过
APP_CFLAGS += -Wno-error=format-security