前言:

  • 在上一篇文章中给小伙伴们介绍了进行Camera预览,如果你还没有看过的话,建议先去看上一篇文章《Android 短视频开发之摄像头预览(二》

  • 本篇文章会介绍如何实现摄像头预览画面实时美颜

原理:

废话就不多啰嗦了,要达到 摄像头实时美颜的效果,从原理上来讲很简单,只要保证每一帧画面经过美颜处理后显示在界面上就完了。

实现思路:

前面的预览过程就不罗嗦了,不懂可以看上一篇文章。

这里有两种方式实现

  1. 在Camera.PreviewCallback回调中直接获取图片数据,然后经过OpengGL处理后再显示出来
  2. 直接让Camera的预览画面渲染在OpengGL的OES纹理中,通过SurfaceTexture把数据交给OpengGL渲染后再渲染到屏幕上

当然第一种缺点很明显就是渲染速度太慢会导致预览异常卡顿,帧率也达不到要求,主要问题在于摄像头获取的数据时YUV格式的数据而,OpenGL渲染是RGBA格式的数据,这就导致要渲染首先要先转换颜色空间,这个转换时比较耗时的。二第二种方式刚好能规避这个问题,直接把这已转换过程让GPU做了,速度非常快。预览和渲染效果很好,而且帧率也能达到要求。所以一般美颜相机类应用都会选择第二种方式来处理。

在这里由于后面的模块都涉及到OpengL渲染,所以需要有一定的OpenGL经验,建议对OpenGL不熟的先学习下基础。网上关于OpenGL的文章有很多这里就不列举了。

具体实现

1.创建OpenGL渲染环境,因为使用的时TextureView所以需要自己创建

  /*** Surface 要显示的TextureView中的surface*/void surfaceCreated(SurfaceTexture surface) {//创建OpenGL环境mEglCore = new EglCore(null, EglCore.FLAG_RECORDABLE);mDisplaySurface = new WindowSurface(mEglCore, surface);//切换到当前上下文环境中mDisplaySurface.makeCurrent();GLES30.glDisable(GLES30.GL_DEPTH_TEST);GLES30.glDisable(GLES30.GL_CULL_FACE);// 渲染器初始化mRenderManager.init(mContext);//创建OES纹理mInputTexture = OpenGLUtils.createOESTexture();//创建SurfaceTexture供Camera.setPreviewTexture()//这里时关键把摄像头的数据映射到SurfaceTexture的纹理当中供后面渲染mSurfaceTexture = new SurfaceTexture(mInputTexture);mSurfaceTexture.setOnFrameAvailableListener(this);// 打开相机openCamera();Log.d("RenderThread","onSurfaceTextureAvailable="+surface);}

2.接收SurfaceTexture的OnFrameAvailableListener的回调

 @Overridepublic void onFrameAvailable(SurfaceTexture surfaceTexture) {requestRender();}

3.在接收到数据变化后就开始渲染数据并显示到屏幕

/*** 绘制帧*/void drawFrame() {if (mSurfaceTexture == null || mDisplaySurface == null) {return;}// 当记录的请求帧数不为时,更新画面while (mFrameNum > 0) {// 切换渲染上下文mDisplaySurface.makeCurrent();//更新图像数据mSurfaceTexture.updateTexImage();mSurfaceTexture.getTransformMatrix(mMatrix);--mFrameNum;// 绘制渲染mCurrentTexture = mRenderManager.drawFrame(mInputTexture, mMatrix);// 显示到屏幕mDisplaySurface.swapBuffers();}}

关键步骤

// 绘制渲染
mCurrentTexture = mRenderManager.drawFrame(mInputTexture, mMatrix);

在这个渲染管理器里完成了图像的渲染

drawFrame干了些什么事情呢?

  /*** 绘制纹理* @param inputTexture* @param mMatrix* @return*/public int drawFrame(int inputTexture, float[] mMatrix) {int currentTexture = inputTexture;if (mFilterArrays.get(VideoRenderIndex.CameraIndex) == null|| mFilterArrays.get(VideoRenderIndex.DisplayIndex) == null) {return currentTexture;}if (mFilterArrays.get(VideoRenderIndex.CameraIndex) instanceof GLImageOESInputFilter) {((GLImageOESInputFilter)mFilterArrays.get(VideoRenderIndex.CameraIndex)).setTextureTransformMatrix(mMatrix);}currentTexture = mFilterArrays.get(VideoRenderIndex.CameraIndex).drawFrameBuffer(currentTexture, mVertexBuffer, mTextureBuffer);// 如果处于对比状态,不做处理if (!mCameraParam.showCompare) {// 美颜滤镜if (mFilterArrays.get(VideoRenderIndex.BeautyIndex) != null) {if (mFilterArrays.get(VideoRenderIndex.BeautyIndex) instanceof IBeautify&& mCameraParam.beauty != null) {((IBeautify) mFilterArrays.get(VideoRenderIndex.BeautyIndex)).onBeauty(mCameraParam.beauty);}currentTexture = mFilterArrays.get(VideoRenderIndex.BeautyIndex).drawFrameBuffer(currentTexture, mVertexBuffer, mTextureBuffer);}//LUT 颜色查找表滤镜if (mFilterArrays.get(VideoRenderIndex.LookupFilterIndex) != null) {if(mFilterArrays.get(VideoRenderIndex.LookupFilterIndex) instanceof GLImage512TwoInputLookupTableFilter){((GLImage512TwoInputLookupTableFilter) mFilterArrays.get(VideoRenderIndex.LookupFilterIndex)).updateBitmap();}currentTexture = mFilterArrays.get(VideoRenderIndex.LookupFilterIndex).drawFrameBuffer(currentTexture, mVertexBuffer, mTextureBuffer);}}// 显示输出,需要调整视口大小mFilterArrays.get(VideoRenderIndex.DisplayIndex).drawFrame(currentTexture, mDisplayVertexBuffer, mDisplayTextureBuffer);return currentTexture;}

其实这里就到了滤镜渲染了。对每帧图片进行了渲染处理。每一个滤镜渲染完交给下一个滤镜渲染达到滤镜组合显示的效果

到此就完成了相机预览画面实时渲染了。

Android 短视频编辑开发之摄像头预览实时美颜(三)相关推荐

  1. Android 短视频编辑开发前言(一)

    系列文章目录 Android 短视频编辑开发前言(一) Android 短视频开发之摄像头预览(二) Android 短视频编辑开发之摄像头预览实时美颜(三) Android 短视频编辑开发之相机拍照 ...

  2. 短视频软件开发中如何实现720P磨皮美颜录制?

    短视频软件开发中如何实现720P磨皮美颜录制? 在Android上要实现一个录制功能,需要有几个方面的知识储备:自定义相机的开发.视频数据格式的了解.编码相关知识以及视频合成技术,同时如果需要美颜.磨 ...

  3. Android短视频app开发中如何实现上下滑动切换效果

    在大部分短视频app开发中,都会在app内增加上下滑动切换视频的功能,即下滑切换到下一条短视频,上滑切回到上一条.这种机制可以给用户带来良好的视觉体验,云豹作为优秀的app源码供应商,在该效果的实现上 ...

  4. android 短视频编辑,短视频编辑制作大师

    短视频编辑制作大师app是一款多功能的手机视频剪辑服务应用软件,短视频编辑制作大师app为用户提供了视频合并.水印去除.视频提取.添加文字.滤镜等等功能,短视频编辑制作大师app轻轻松松编辑好视频. ...

  5. android 短视频编辑,分享Android短视频制作(最简洁的一个)

    下面制作完后短视频效果图,如下: 短视频动态图 看完效果图,是不是觉得很简单,现在开始讲一下,如何制作短视频,具体做法如下介绍: 准备材料并配置项目工程: 1.去下载七牛云播放器SDK 2.然后把pl ...

  6. 基于camera2 untiy悬浮窗摄像头预览分析

    前言 在某机系统上 unity 导出的android 工程 使用camerax 悬浮窗口 bindToLifecycle 加上预览界面就显示不出来(手机上没问题,原因没找到),不得以 改用camera ...

  7. Android短视频开发都需要什么技术?

    今天我们来讲点干货,估计来看这篇帖子的人都知道短视频APP有多火,也都知道安卓系统在手机系统中占的市场份额有多大,那我就不多嘴巴拉巴拉一些行业背景了,以下我着重讲一讲Android端的短视频开发技术. ...

  8. android短视频技术,Android短视频开发都需要什么技术?

    今天我们来讲点干货,估计来看这篇帖子的人都知道短视频APP有多火,也都知道安卓系统在手机系统中占的市场份额有多大,那我就不多嘴巴拉巴拉一些行业背景了,以下我着重讲一讲Android端的短视频开发技术. ...

  9. 【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )

    文章目录 安卓直播推流专栏博客总结 一. Android 端数据采集涉及到的相关概念 二. Camera 预览图像尺寸设置 三. 获取摄像头采集的数据格式 安卓直播推流专栏博客总结 Android R ...

最新文章

  1. 控件测试功能点摘要2
  2. MYSQL免安装版-安装配置过程
  3. MySQL复制常见问题处理
  4. 使用 Core Graphics 绘制基本形状
  5. 前魅族副总裁李楠上手魅族17:颜值提升了
  6. 如何远程进入linux7.2图形界面,CentOS7.2安装VNC,让Windows远程连接CentOS 7.2 图形化界面...
  7. scala特性_Scala特性示例教程
  8. 注解的DI以及动态代理
  9. Fluent NHibernate other example
  10. Appium下载及环境搭建
  11. 分享一种MODIS数据下载方法
  12. 有关彩虹猫病毒的一些小小的分析
  13. java程序员必备快捷键
  14. ps怎么撤销参考线_PS怎么拉辅助线和清除、移动参考线——视频教程十
  15. Zigbee 应用层协议自定义
  16. Diamond安装步骤
  17. 联想模拟器安装激活面具magisk教程
  18. java 把ascll转换成char_java中 怎么把一个ascii转换成字符串
  19. source insight
  20. 个人千元奖励!华秋PCB多层板设计挑战赛等您参与

热门文章

  1. phpmyadmin 4.8.1 Remote File Inclusion Vulnerability (CVE-2018-12613)漏洞复现
  2. SOLIDWORKS Electrical无缝集成电气和机械设计
  3. ue4 获取屏幕中心点坐标
  4. Android之Surface 与 SurfaceFlinger关系
  5. 未来公园怎么能少了广场舞?
  6. Golang使用mgo.v2包操作MongoDB的基础示例
  7. 糅合不好变搀合,搀合不好变搅合
  8. SQLServer DBA 六十问
  9. 服务器国产linux操作系统,国产linux操作系统适于做服务器系统的有哪些
  10. 获取android模拟器的IP地址