一次android滤镜实现的尝试

背景是看这几年视频,尤其是短视频,剪辑软件等很火,甚至可以虚拟交互,就想看看是怎么做的。

 

搜了一下,目前而言开源的内容还是很多的,android这块剪辑滤镜等还好,虚拟相关的好多都是unity。于是就想着说能搞个东西,本身负责剪辑处理,虚拟部分用unity去搞。

漫长的开始了...

 

(一).尝试android中接入unity项目。

android工程里嵌套一个unity项目,在用的时候去加载unity资源,不用的时候释放掉。

写之前例行百度,恩,找到一篇不错的内容https://www.jianshu.com/p/374f1bc287ef,开工!

 

首先是unity工程,找个unitydemo。运行,确认工程本身没毛病。新建一个android工程,同样先配置环境能跑起来。

 

接着打包unity到android工程。

这里主要涉及unityclass.jar文件的迁移以及asset及lib的移动。具体的方法网上很多,就不记录了。为了调试方便,避免频繁移动耗时,这里写了个小工具:

https://blog.csdn.net/l304847944/article/details/89214810

 

android这边的思路是:先把unity官方导入的类写进来(UnityPlayerActivity)

尝试启动,发现最小api太低,再次启动。哦,没有加入一些必要的权限,再次尝试。运行起来了。

 

但是发现unity开头logo很难看。百度,有破解工具破解专业版能实现,但是侵权。白嫖失败。

 

继续,虽然能跑起来了,但是没办法返回回来,加了个按钮,调用unity的退出方法。额...尝试了发现会闪退。看参照的文档,确实会有问题。一步一步跳转源码发现,unity的退出确实是直接退出进程了。 Process.killProcess(Process.myPid());

 

参照文档尝试用singleinstance来跑,发现并不成功。

 

百度后找到个解决方案,新开一个进程来处理退出。试了下,完美。

查看相关代码发现,unity在android中主要是通过addview去把画布加进去,并设定渲染层级到UI最顶部来绘制,使用surface来渲染。

到此,确实unity项目可以这样的方式接入进来,思路可行。

 

(二)(android)虚拟交互逻辑的思考

首先经过大量的搜索,目前市场上的交互大致分两种,可穿戴设备的和非穿戴设备的。可穿戴的主要有htvvive,罗技,以及医用的一些辅助设备,最近很流行的健身环大冒险也算是一种。而不使用可穿戴设备的主要是一些像kinect,xbose的一些游戏。

 

就android而言,如果佩戴可穿戴设备好像意义并不大(之前的暴风魔镜配置的蓝牙手柄这种使用局限太大,仅在vr眼镜场景才能使用,否则很鸡肋,不适于大量推广。),单纯的手机(无其他辅助设备),好像人脸交互,一些场景的滤镜,美颜效果不就是这方面很好的例子么,那么,先找找原理。

 

经过百度以及自我分析(可能有误)(以kinect为例),大致原理是通过设备的摄像头,红外线(包含深度感知和温度感知),绘制相关的温度图,灰度图,轮廓图(去色反相背景叠加调整色阶),颜色值图片(正常相片)来进行时时的数据获取和处理。

 

(红外热成像图)

这样的话,可以考虑利用识别紫色,讲紫色背景抠掉,添加自己的背景。唉嘿,这不就是王老菊他们直播时候只显示个人(没有任何摄像机背景的功能嘛!)

(源于网络,侵删)

 

那么,对于安卓手机而言,可以实现么?

额,好像,首先需要红外热成像功能,百度下

发现无论是github还是一些相关文档,都没有相关的api,然后查功能,发现确实没有相关的功能。即使是红外的深度检测功能,也只找到17年出的一篇可能加入的功能预告(高通)https://www.theverge.com/circuitbreaker/2017/8/15/16150166/qualcomm-snapdragon-spectra-image-processor-android-phones-depth-sensing-ir-camera

 

先不去理会这块的代码复杂程度,就手机而言,人脸识别、抖音的滤镜(长腿特效,景物镜面等)是怎么的原理呢,经过到处翻阅,发现其实依旧是通过成像+图像处理(opencv)实现。opencv百度了下,大致目前都是c++,c的代码。部分有封装的其他语言,但是很少,这块用ndk转接入行得通么?还是说抖音这类是自己用android实现了次。值得思考。

暂时不谈这个,先试试基本的成像功能。

 

(3)一次图像镜面滤镜的尝试

百度了下,发现有,但是完全看不懂啊...硬着头皮来吧

首先是要接入opengl,android是openes(相当于是对一些库进行了整合使用),目前而言基本可用是javax.microedition.khronos.egl这个包的内容

参照:https://www.jianshu.com/p/95dfe935b169 

 

同opengl一样,首先是初始化,包含display(获取句柄),初始化相关库(init),选定配置(config),不同于opengl的texture2d,这里的画布不再需要自己去创建而可以使用surface(android的画布板)。

 

(这里可以简单说明下surface的创建和回调含义)https://www.jianshu.com/p/8fa3eed3c975

 

 

这里可能需要先看下水镜像的原理:就是把图片像素格子大致取合适的点(比如中间),然后下半部分绘制时候反过来用上半部分的像素值去绘制。这样就会形成镜面效果

 

(fsh文件如图所示)

 

这里可以简单说下cpu与gpu的区别,以及为啥要在gpu上面绘制。以及android openes渲染管线,顶点着色器,片源着色器(简单说明吧,具体特别深入我也还没弄清)https://www.jb51.net/article/140874.htm

 

继续,读取写好的定点着色器以及片源着色器文件,去执行双缓冲绘制,多次调试(这里openes的调用顺序很重要,稍有一步反了就会出不来,踩坑了),完成。

 

后续一些思考,这里的openes绘制功能看着很完全,那么,为何原生很少见对shader的使用呢?考虑到shader技术的难度,去shadertoy里面搬运来的shader有没有可能去接进来用呢?暂时还是有些问题的(观察发现部分gc代码和库代码android不支持,也可能有替代实现的可能性,这个还在尝试中...)

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值