Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.2 来一份LOMO滤镜
来源:互联网 发布:淘宝卖家信息采集软件 编辑:程序博客网 时间:2024/04/30 12:14
Github项目地址
回到目录
了解了滤镜的基本知识以后,我们就可以试着来做我们的第一个滤镜了
虽然之前做过一个灰度滤镜,但是是采用直接修改片元着色器代码的方式,非常“不优雅”,所以这次我们试着来搭一个框架,让增加新的滤镜变得更加容易。
由于相关代码过多,本文只会贴出关键部分,其余的请去项目中查找
省略的内容包括但不限于:
- 类似GPU-Image的滤镜组
- 相关工具类
固定顶点着色器
由于大部分滤镜都是在片元着色器当中进行,我们可以直接固定顶点着色器部分的代码
代码很简单,只有顶点相关信息
attribute vec4 aPosition;attribute vec4 aTextureCoord;varying vec2 vTextureCoord;void main() { gl_Position = aPosition; vTextureCoord = aTextureCoord.xy;}
然后写一个简单的类包装一下,以后我们只修改fragmentShader的滤镜都可以继承这个类
public class SimpleFragmentShaderFilter extends AbsFilter { protected GLSimpleProgram glSimpleProgram; protected Plain plain; public SimpleFragmentShaderFilter(Context context, final String fragmentShaderPath) { glSimpleProgram=new GLSimpleProgram(context, "filter/vsh/simple.glsl",fragmentShaderPath); plain=new Plain(true); } @Override public void init() { glSimpleProgram.create(); } @Override public void onPreDrawElements() { super.onPreDrawElements(); glSimpleProgram.use(); plain.uploadTexCoordinateBuffer(glSimpleProgram.getTextureCoordinateHandle()); plain.uploadVerticesBuffer(glSimpleProgram.getPositionHandle()); } @Override public void destroy() { glSimpleProgram.onDestroy(); } @Override public void onDrawFrame(int textureId) { onPreDrawElements(); TextureUtils.bindTexture2D(textureId, GLES20.GL_TEXTURE0,glSimpleProgram.getTextureSamplerHandle(),0); GLES20.glViewport(0,0,surfaceWidth,surfaceHeight); plain.draw(); }}
来一份LOMO滤镜
严格来说这个应该是炫影(Vignette)效果,而不是LOMO效果
/** * Created by Ads on 2017/1/31. * VignetteFilter (炫影) */public class VignetteFilter extends SimpleFragmentShaderFilter { public VignetteFilter(Context context) { super(context, "filter/fsh/mx_vignette.glsl"); }}
类的代码异常简单有没有,因为变化的只有着色器代码而已
美丽的滤镜背后都是数学和艺术在支撑,但是本文暂时还不会详细阐述每个滤镜的原理,代码来自某个相机app(侵删),就直接贴出来吧
mx_vignette.glsl
precision mediump float;uniform sampler2D sTexture;varying vec2 vTextureCoord;vec4 calVignette2(vec4 color, vec2 coord, float strength) { float distance = (coord.x - 0.5) * (coord.x - 0.5) + (coord.y - 0.5) * (coord.y - 0.5); float scale = distance / 0.5 * strength; color.r = color.r - scale; color.g = color.g - scale; color.b = color.b - scale; return color;}vec4 calNewSaturation(vec4 color,float saturation) { float gray = dot(color.rgb, vec3(0.299,0.587,0.114)); return vec4(gray + (saturation / 100.0 + 1.0) * (color.r - gray), gray + (saturation / 100.0 + 1.0) * (color.g - gray), gray + (saturation / 100.0 + 1.0) * (color.b - gray), color.a);}void main() { vec4 color = texture2D(sTexture, vTextureCoord); color = calVignette2(color, vTextureCoord,1.0); color = calNewSaturation(color, 57.0); gl_FragColor = color;}
效果预览
把刚做好的滤镜加进滤镜组:
filterGroup.addFilter(spherePlugin);filterGroup.addFilter(new VignetteFilter(statusHelper.getContext()));
这个滤镜放在渲染到球体之后(如果放在前面又是另一番效果)。可以和原图对比一下:
是不是感觉不加滤镜简直丑爆了(虽然加了好像也好看不到哪里去嘛)?
Github项目地址
回到目录
0 0
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.2 来一份LOMO滤镜
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——参考资料
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.4 滤镜以及配套代码的制作方法
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.2 GPGPU解决方案简述
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.1 GPUImage结构简析
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——4.1高仿FaceU长按录像按钮
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.1 GPUImage结构简析
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.3 仿制Snow相机和FaceU的边框/小脸模式
- 【OpenGL】 Android平台美颜相机、实时滤镜、人脸技术探秘
- Android平台Camera实时滤镜实现方法探讨(八)--滤镜基本制作方法(二)简单美颜滤镜
- Android平台Camera实时滤镜实现方法探讨(八)--滤镜基本制作方法(二)简单美颜滤镜
- Android平台Camera实时滤镜实现方法探讨(十一)--实时美颜滤镜
- Android平台Camera实时滤镜实现方法探讨(十一)--实时美颜滤镜
- Android Camera 实时滤镜
- 【Camera】Android平台Camera实时滤镜实现方法
- Android Camera 实时滤镜 (二)
- Android平台Camera实时滤镜实现方法探讨(四)--以Hefe滤镜为例
- Android平台Camera实时滤镜实现方法探讨(七)--滤镜基本制作方法(一)
- 【NOI2012】随机数生成器
- CJOJ P2317 JesseLiu的预算方案
- 为什么1000 == 1000返回为False,而100 == 100会返回为True?
- 【JZOJ 3693】 慎二的随机数列
- 用51单片机+11.0592的晶振,如何产生115200的波特率
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——2.2 来一份LOMO滤镜
- 初出茅庐
- 折纸问题
- 程序功能:建立一个带有头结点的单向链表,并将存储在数组中的字符依次转储到链表的各个结点中。
- String类的intern()方法详解
- Redis源码解析——字典遍历
- 为什么要做A.prototype.constructor=A这样的修正?
- [Leetcode] #104 Maximum Depth of Binary Tree
- mysql免安装版安装教程