回顾

在前面视频录制篇尾(https://www.jianshu.com/p/4f63b2436401)中有提到视频录制+人脸识别+贴纸的想法,而上一篇(https://www.jianshu.com/p/6d2d4f00b43c)中也使用opengl实现了多种特效,在这些技术与理论基础上能否实现市面上常见的动态贴纸效果呢?

效果图

先来个效果图,这个是抓取QQ的资源包来做的:

视频动态贴纸特效.gif

分析

素材解析

刚开始看到QQ的这个拍摄特效时,觉得很有意思,又正好之前就想着研究一下动态贴纸的做法,于是在sd卡中找到QQ的文件目录.../tencent/MobileQQ/capture_ptv_template/ptv_template_usable/video_qiuhongbaowu3_iOS/,里面有bgm、hongbao两个目录和params.json文件,bgm中是背景音乐mp3文件,hongbao中是80张素材图片,params.json是规则配置文件。

至此大体能知道,其实视频动效是由一系列图片连续显示的效果。查看params.json,里面包含类型定义、显示时间间隔、素材列表及显示顺序,同时每个素材信息还包括镂空中心点、镂空区域大小、旋转角度等信息。显然这个镂空区域是用来填充人脸的,这样人脸图像放在底层,贴纸在上层,需要让镂空区域与人脸重合,以便看起来就像是人脸在贴纸上的效果。

原理与关键点分析

解析素材后可以看出,根据配置文件,对素材列表根据顺序及时间间隔,不断替换显示出来,其实视频也是这个原理。现在有个问题:怎么让素材图片隔段时间替换一张,不断显示出来呢?

前面文章中的视频录制,就是需要设置帧率,也就是说每隔一段时间都会刷新画面,如果我们设置filter,那么每个filter的draw就会在刷新时被调用。所以我们写一个filter,解析配置文件得到文件列表及其他信息,这样在draw函数中,每次根据时间来判断当前应该画哪一张图:

...

if (this.loopStartTime == -1L) {

this.loopStartTime = System.currentTimeMillis();

}

int currentIndex = (int) ((System.currentTimeMillis() - this.loopStartTime) / this.mSticker.frameDuration);

if (currentIndex >= this.mSticker.frameCount) {

if (!this.mSticker.looping) {

this.loopStartTime = -1L;

this.lastIndex = -1;

return;

}

currentIndex = 0;//新一轮中从第一张开始显示,并重新计时

this.loopStartTime = System.currentTimeMillis();

}

if (currentIndex < 0) {

currentIndex = 0;

}

StaticImage image = mSticker.images.get(currentIndex);

if (this.lastIndex != currentIndex) {

mTexture.load(image.path);//加载图片

}

...

对于渲染图片,在之前的demo中已经有现成源码可以使用,那如何把头像绘制到贴纸的镂空位置呢?

头像抠图

人脸识别可以借助第三方的sdk,face++、商汤等收费的,识别效果比较好,主要是识别到的关键点比较多,或者讯飞的免费,基本能够满足。

根据识别结果的头像区域,再计算贴纸镂空区域位置与大小,使用glsl做渲染位置计算:

precision highp float;

varying highp vec2 vCamTextureCoord;

uniform sampler2D uCamTexture;

uniform vec4 srcRect;//头像在源画面(画布)中的位置

uniform vec4 dstRect;//头像在新画布中的位置

void main(){

lowp vec4 c1 = texture2D(uCamTexture, vCamTextureCoord);

//注意这个y坐标的计算,因为屏幕坐标第的Y轴方向与纹理的Y轴方向是相反的

lowp vec2 vCamTextureCoord2 = vec2(vCamTextureCoord.x,1.0 - vCamTextureCoord.y);

vec2 point = vCamTextureCoord2;

if(point.x>dstRect.r && point.xdstRect.g && point.y

{

//这个需要根据缩放比例来计算真实位置

vec2 imagexy = vec2(

(srcRect.b - srcRect.r) * (point.x - dstRect.r) / (dstRect.b - dstRect.r) + srcRect.r,

1.0 - ((srcRect.a - srcRect.g) * (point.y - dstRect.g) / (dstRect.a - dstRect.g) + srcRect.g)

);

c1 = texture2D(uCamTexture, imagexy);

}

gl_FragColor = c1;

}

至此,我们可以这样理解这个过程:

原始画面 -> 抠头像 -> 画贴纸

即两次渲染,得到合成的画面,再加上时间间隔及不同贴纸的显示,就得到上术的效果。

由于我们在抠头像后是绘制到当前贴纸的镂空位置,这样无论头像在原始画面的什么位置,只要能识别出来,都不会影响抠图操作及最终效果。

总结

现在来看,动态贴纸从原理上其实也是很简单的,而且组合方式很多,所以才能看到很多APP上有那么多的贴纸模版,当然有些是有加入肢体识别的,比如QQ,这方便鹅厂坐的很好。

其实也要“感谢”那些第三方SDK的收费,还有XXX的UOK,促使我们自己来研究这些。

吐槽一下,对于那些本来没有基础、不想花钱,而还想要达到别人的精致效果的,那就只能呵呵了。

本文相关的代码暂时不会更新到DEMO中,其实思想比较重要。

android 仿qq发动态,Android opengl 实现动态贴纸(仿QQ的拍摄)相关推荐

  1. android系统休眠发广播,Android - BroadcastReceiver

    BroadcastReceiver BroadcastReceiver,广播接收者,用来接收系统和应用的广播,并做出相应的处理,如电量过低时提示用户充电等: BroadcastReceiver 是 A ...

  2. qq发消息时键盘挡住了_实现QQ聊天输入框下的工具栏不被软键盘遮挡

    一般情况下,输入法弹起来都在获取焦点的输入框下面,这样的情况就会把输入框下面的内容给遮挡住,但是发现QQ的聊天页面不会,工具栏一样显示在输入框下面.可以下下面图效果 QQ效果.png 一般情况下.pn ...

  3. phpmail通过qq发邮箱失败_PHP中利用PHPMailer配合QQ邮箱实现发邮件

    phpmailer实现给网站用户发送邮件,WordPress好像禁用了mail()函数,也不能直接使用自带的发送邮件,以防止暴露IP PHPMailer的介绍: 可运行在任何平台之上 支持SMTP验证 ...

  4. android写qq动态界面,Android_Android仿QQ空间主页面的实现,今天模仿安卓QQ空间,效果如 - phpStudy...

    Android仿QQ空间主页面的实现 今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: ...

  5. android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...

  6. android仿qq动态,Android仿QQ空间主页面的实现

    今天模仿安卓QQ空间,效果如下: 打开程序的启动画面和导航页面我就不做了,大家可以模仿微信的那个做一下,很简单.这次主要做一下主页面的实现,下面是主页面的布局: android:layout_widt ...

  7. android仿微博发动态,Android GridView扩展仿微信微博发图动态添加删除图片功能

    在平时的开发中,我们会看到不管是微信发朋友圈照片还是微博发布新鲜事,添加图片的时候都是选完后面还有个+号再去选择图片,这样的话比较方便用户去添加图片,有的右上角还有个-号方便用户去删除图片,而一般用户 ...

  8. Android Studio百度地图仿QQ发说说选择位置功能

    此功能实现也相对简单,主要是对百度地图的应用,以及Android基础的知识. 百度地图用到了定位功能和附近POI搜索功能. 效果图: 实现步骤.思路: 1.新建Android项目 2.创建AK. 打开 ...

  9. Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展

    本文由"猫爸iYao"原创分享,感谢作者. 1.引言 最近有个需求:评论@人(没错,就是IM聊天或者微博APP里的@人功能),就像下图这样: ▲ 微信群聊界面里的@人功能  ▲ Q ...

  10. android+qq底部界面,Android 高仿QQ 界面滑动效果

    Android高仿QQ界面滑动效果 点击或者滑动切换画面,用ViewPager实现, 首先是布局文件: android:layout_width="match_parent" an ...

最新文章

  1. 搭建turnserver
  2. docker清空为none的镜像
  3. “不厚道”的程序员:年后第一天上班就提辞职?
  4. ML之DR之PCA:利用PCA对手写数字图片识别数据集进行降维处理(理解PCA)
  5. gpu超算算法_超算安装GPU-based软件 (以pytorch为例)
  6. NIO(一)——缓冲区Buffer
  7. 期刊分类abcde_期刊分类
  8. 2021-08-13 sql练习
  9. 抖音上热门的好处有哪些?
  10. 解决PC微信版本过低 1.0.7.33版本及以上版本方法
  11. 经典算法研究系列:八、再谈启发式搜索算法
  12. hdu 5238 Calculator(线段树+CRT)
  13. Tofu Icecream and Tai-chi man
  14. shell批量修改文件名字 重命名 MD5+文件后缀
  15. Jenkins任务调度源码简要分析
  16. 微信小程序 :模仿酷狗音乐播放器等界面
  17. ReentrantLock 原理(源码轰炸)
  18. 北京bgp机房和普通机房的区别
  19. d2lzh_pytorch
  20. 电视云视听服务器无响应怎么回事,云视听企鹅停服怎么办?原因是什么?

热门文章

  1. 【Android】应用拍摄视频功能
  2. iOS 手机常见功能总结(一)
  3. UVa 10934 Dropping water balloons:dp(递推)
  4. web利用html2canvas实现截图上传图片
  5. S3DIS数据集的几个bug
  6. RT-AC87U华硕路由器外网登陆
  7. lopa分析_保护层分析(LOPA)
  8. python画五角星和六角星程序_python画五角星和六角星程序
  9. java毕业设计项目基于JavaWeb酒店管理系统开发与设计
  10. mac终端提示You have not agreed to the Xcode license agreements.