Android和JavaWeb通性跨平台之C的应用
我们都知道Java是一门跨平台语言,能够跨平台的原因是虚拟机,根本原因是虚拟机是用C语言写的,大部分操作系统都支持C开发,是通过JNI Java调用C程序实现的。
跨平台C应用有三个核心的分别是:
一。图形 OpenGL
常用的游戏引擎是通过JNI Java调用OpenGL C 库来实现的,前提条件是操作系统本身支持OpenGL,从而实现跨平台。为了说明清楚,用以下代码来说明,以下是一个通过OpenGL C代码来渲染的类,从#include<GLES2/gl2.h>可以看出调用系统的OpenGL库。
#ifndef NATIVEGL_DEMO2_GLINTERFACE_H
#define NATIVEGL_DEMO2_GLINTERFACE_H
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <pthread.h>
#include <cstdlib>
#include <math.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <unistd.h>
#include <sys/time.h>
#include <initializer_list>
#include <memory>
#include <memory.h>
#include <jni.h>
class RenderPara{
public:
enum RenderThreadMessage {
MSG_NONE = 0,
MSG_WINDOW_SET,
MSG_RENDER_LOOP_EXIT
};
pthread_t _threadId;
pthread_mutex_t _mutex;
enum RenderThreadMessage _msg;
// android window, supported by NDK r5 and newer
ANativeWindow* _window;
EGLDisplay _display;
EGLSurface _surface;
EGLContext _context;
EGLint _width;
EGLint _height;
};
class GLRenderer {
private:
RenderPara renderPara;
// int start;
bool Inited=0;
bool running=0;
bool window_seted=0;
public:
/*
* 下面的函数为GLRender类内置函数,用户不需要实现
* 其中声明为virtual的函数用户程序可覆盖实现
* */
GLRenderer();
~GLRenderer();
virtual GLuint loadShader(GLenum shaderType, const char* pSource); //加载着色器脚本(用户可调用
virtual GLuint createProgram(const char* pVertexSource, const char* pFragmentSource); //创建OpenGL渲染工程(用户可调用
virtual bool InitRender(); //初始化EGL
virtual void DestroyRender(); //清除EGL
static void * RenderThread(void *args); //OpenGL渲染线程入口
virtual void RenderLoop(); //渲染线程主循环
/*
* 将OpenGL渲染的窗口关联到java空间的Surface对象。实现在SurfaceView上的绘图
* @env:JNI方法传入的JNIEnv对象
* @surface:Surface对象
*/
virtual void SetWindow(JNIEnv *env, jobject surface);
/*
* 开启OpenGL渲染线程。第一次调用时创建渲染线程。
* 之后调用只是继续运行调用StartRenderThread函数后停止的渲染线程,并不会重新开启一个渲染线程。
* 也就是说,每个GLRenderer对象只能创建一个渲染线程
* */
virtual void StartRenderThread();
/*
* 停止渲染线程,并不会释放线程资源,只是停止线程运行。
* 当再次调用StartRenderThread函数后,线程继续运行。
* */
virtual void StopRenderThread();
/*
* 下面三个函数为OpenGL渲染上下文回调函数,这三个函数需要用户通过继承GLRenderer类的方法来实现
* 实现方法同android.opengl.GLSurfaceView.Render中的方法。详细请参考develop.google
* */
virtual void SurfaceCreate()=0;
virtual void SurfaceChange(int width, int height)=0;
virtual void DrawFrame()=0;
};
#endif //PHASEDARRAY2_0_GLINTERFACE_H
从以下代码我们可以看出是通过JNI 调用C实现跨平台:
import android.view.Surface;
public class JNIProxy {
static {
System.loadLibrary("native-lib");
}
//初始化函数
public static native void CalPixel();
//OpenGL函数--使用Native方案调用OpenGL使用下面6个函数
public static native void StartRenderS();
public static native void StopRenderS();
public static native void SetSurfaceS(Surface surface);
}
二。图像 OpenCV
OpenCV大部分代码是用C写的,包括算法,只有部分是用Java写的,也是一个跨平台的计算机视觉库。以下就是OpenCV用C写的库,通过JNI Java调用相应的库。
OpenCV模块结构:
- Core模块:定义基本的数据结构,包括重要的Mat和一些其他的核心部分。
- Imageproc模块:该模块包括线性和非线性的图像滤波,图像几何变换,颜色转换,直方图处理等等。
- Imagecodecs模块:图像的输入输出模块。
- Video模块:该模块是视频分析,包括运动估计,和背景分离,对象跟踪。
- Calib3d模块:基于多视角几何算法,单个立体摄像头标定,物体姿态估计,立体相识算法,3D信息的重建。
- Features2d模块:显著特征检测,描述,特征匹配。
- Objdetect模块:物体检测和预定义好的分类器实例(比如:人脸,眼睛,面部,人,车等等)。
- HighGUI模块:视频捕捉,图像和视频编解码,图像交换界面。
- GPU模块:利用GPU对OpenCV模块进行加速算法。
- DNN模块:深度神经网络库。
- ML模块:机器学习模块(包括:svm,决策树,Boosting等算法封装)。
- Flann模块:快速最近邻搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的简称。它是一个对大数据集和高维特征进行最近邻搜索的算法的集合,而且这些算法都已经被优化过了。在面对大数据集是它的效果要好于BFMatcher。
- Legacy模块:一些已经废弃的代码库,保留下来做版本兼容。
- 其他模块:Google测试包,Python bingdings等等。
- 额外库模块opencv_contrib:参考博文:https://blog.csdn.net/zmdsjtu/article/details/80736258
以下来说说OpenCV的应用,它的应用与本篇博客联系不大,就一带而过,提一下:
OpenCV的应用有哪些呢:
- 二维与三维特征工具箱
- 运动估算
- 人脸识别
- 姿势识别
- 人机交互
- 运动识别
- 对象识别
- 对象检测
- 移动机器人
- 图像分割与识别
- 视频分析
- 运动跟踪
- 图像处理
- 机器学习
- 深度神经网络
三。音视频 FFmpeg
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它也是跨平台的,底层是用C写的,以下是相应的库,可以通过JNI java调用。
FFmpeg的模块结构:
- libavformat模块:用于各种音视频封装格式生成和解析。包括获取解码所需要信息,以生成解码上下文结构和读取音视频等功能。音视频格式解析协议,为libavcodec分析码流提供独立音频或视频码流源。
- libavcodec模块:用于各种类型声音/图像编解码。读库是音视频编解码的核心,实现了市面上大部分解码器的功能。
- libavdevice模块:用于硬件采集加速,显示,操作计算中常用的音视频捕捉和输出设备。
- libavfilter模块:用于音视频滤波器开发,比如:宽度比剪切,格式化和非格式化伸缩。
- libavutil模块:包括一些公共的工具函数的使用库,如算数运算和字符操作。
- libavresample模块:音视频封装解码格式预设等。
- libswscale模块:原始视频格式转换。
- libswresample模块:原始音频格式转换。
- libpostproc模块:用于音视频后期效果处理,比如:图像去块效应。
以下来说说FFmpeg的应用,它的应用与本篇博客联系不大,就一带而过,提一下:
FFmpeg的应用有哪些呢:
- 音视频剪切和拼接
- 音频混音
- 音频转码
- 音频,视频合成
- 音频抽取
- 音频解码播放
- 音频编码
- 视频抽取
- 视频剪切
- 视频转码
- 视频截图
- 视频转GIF动画
- 视频加水印
- 视频画面拼接
- 视频反序倒播
- 图片合成视频
- 视频解码播放
- 本地直播推流
- 实时直播推流