怎么增加网站反链,vs网站开发建表怎么肩啊,淮安建设工程协会网站查询系统,有开源项目做的网站“当你改变想法的时候#xff0c;记得也要改变你的世界。”——诺曼文森特皮尔 Android OpenGLES开发#xff1a;EGL环境搭建Android OpenGLES2.0开发#xff08;一#xff09;#xff1a;艰难的开始Android OpenGLES2.0开发#xff08;二#xff09;#xff1a;环境搭… “当你改变想法的时候记得也要改变你的世界。”——诺曼·文森特·皮尔 Android OpenGLES开发EGL环境搭建Android OpenGLES2.0开发一艰难的开始Android OpenGLES2.0开发二环境搭建Android OpenGLES2.0开发三绘制一个三角形Android OpenGLES2.0开发四矩阵变换和相机投影Android OpenGLES2.0开发五绘制正方形和圆形Android OpenGLES2.0开发六着色器语言GLSLAndroid OpenGLES2.0开发七纹理贴图之显示图片Android OpenGLES2.0开发八Camera预览Android OpenGLES2.0开发九图片滤镜
前言
还记得我们在Android OpenGLES2.0开发一艰难的开始这一篇中说到OpenGL ES能做什么吗其中一项就是对图片做处理色调转换美颜等。专业的说法叫做滤镜主要是用来实现图像的各种特殊效果。
学了这么久的OpenGL ES不知道大家有没有疑问发现OpenGL ES没有必须要用它的场景画三角形、正方形、圆形完全可以用Android自定义视图实现Camera预览使用OpenGL ES绕了一大圈还是显示摄像头数据。之前学习的场景似乎使用普通模式都能够又快又好的实现OpenGL ES貌似不是必需品。
如果你有这些疑问那么你确实在思考了。其实开发就是这样一个问题可以有多种方案实现无非就是不同方案的优劣罢了。
灰度图的思考
我们知道图像都是由一个一个像素组成的而每一个像素的颜色都由一个RBG值确定由此组成了一副美丽的图像。
如果我们现在要将一副彩色的图像灰度化就要对每一个像素点做处理。一般的处理方法是将图片颜色值的RGB三个通道值设为一样这样原本的256*256*256种颜色就只有256种了256种颜色值就丢失了图片的彩色信息留下的只有亮度值视觉上看上去就是灰色的图片。
灰度处理一般有三种算法
最大值法即新的颜色值RGBMax(RGB)这种方法处理后的图片看起来亮度值偏高。平均值法即新的颜色值RGB(RGB)3这样处理的图片十分柔和加权平均值法即新的颜色值RGB(R WrGWgBWb)一般由于人眼对不同颜色的敏感度不一样所以三种颜色值的权重不一样一般来说绿色最高红色其次蓝色最低最合理的取值分别为Wr 30Wg 59Wb 11
其实知道了上面的算法图像灰度处理就变得简单了无非就是循环遍历图像像素一个一个修改就好了。一张1920*1080的图片有2073600像素点如果使用CPU进行遍历无异于大炮打苍蝇出力不讨好。这个时候GPU的并行处理能力就派上用场了而OpenGL ES又是GPU的驱动所以OpenGL ES什么时候用我想大家也就明白了。
加权平均值法
我们使用加权平均值法对图片进行灰度化处理我们拷贝Image类修改为GrayFilter修改片段着色器代码如下
// 灰度片段着色器代码
private final String grayFragmentShaderCode precision mediump float;\n uniform sampler2D vTexture;\n varying vec2 aTexCoordinate;\n void main() {\n vec4 rgba texture2D(vTexture, aTexCoordinate);\n float color rgba.r * 0.3 rgba.g * 0.59 rgba.b * 0.11;\n gl_FragColor vec4(color, color, color, 1.0);\n }\n;为了使GrayFilter更加通用我们不再内部传入Bitmap生成纹理而是外部传入纹理进行渲染修改onDraw方法如下
public void onDraw(int textureId, float[] matrix)我们使用这个灰度滤镜渲染一张1080*2041大图看下哇哦看着效果确实不错。本人使用测试手机是2018年发布的一加6T渲染时间不到1ms可见OpenGL ES对图像强大的处理能力。 几种常用滤镜实现
1. 反相
反相是一种特殊的图像处理方式其作用是将原图中的明暗颜色值反转即明的地方变暗暗的地方变亮。具体操作就是用255分别减去RGB三个值作为新的RGB颜色。直接上片段着色器代码
private String fragmentShaderCode precision mediump float;\n uniform sampler2D vTexture;\n varying vec2 aTexCoordinate;\n void main() {\n vec4 rgba texture2D(vTexture, aTexCoordinate);\n gl_FragColor vec4((1.0 - rgba.rgb), 1.0);\n }\n;应为GL中对色值进行的归一化为 [0-1.0] 所以代码中使用1.0减去对应的色值
2. 亮度
亮度是人对光的强度的主观感受通常用堪德拉每平米cd/m²或尼特来表示。在PS中亮度调整是通过改变图像中像素的光亮度来实现的从而影响图像的明暗程度。提高亮度可以使图像变得更加明亮减少阴影区域增强图像的通透性反之降低亮度则会使图像变暗增加画面的沉稳感或神秘氛围。
调整亮度只需要RGB色彩空间里面同时加上一个程度值。
private String fragmentShaderCode precision mediump float;\n uniform sampler2D vTexture;\n uniform lowp float brightness;\n varying vec2 aTexCoordinate;\n void main() {\n vec4 rgba texture2D(vTexture, aTexCoordinate);\n gl_FragColor vec4((rgba.rgb brightness), 1.0);\n }\n;brightness为正表示提亮为负表示变暗
3. 冷暖色调
暖色系调整是加强R/G来完成
float[] changeColor {0.1f, 0.1f, 0.0f};冷色系调整是增加B的分量
float[] changeColor {0.0f, 0.0f, 0.1f};着色器代码如下我们通过外部传入色值来改变原图色调并且最后限制色值范围为**[0-1]**
private String fragmentShaderCode precision mediump float;\n uniform sampler2D vTexture;\n uniform vec3 vChangeColor;\n varying vec2 aTexCoordinate;\n // 控制颜色在[0-1]范围vec4 clampColor(vec4 color) {\n return vec4(clamp(color.r, 0.0, 1.0), clamp(color.g, 0.0, 1.0), clamp(color.b, 0.0, 1.0), 1.0);\n }\n void main() {\n vec4 srcColor texture2D(vTexture, aTexCoordinate);\n vec4 dstColor srcColor vec4(vChangeColor, 0.0);\n gl_FragColor clampColor(dstColor);\n }\n;其实这套代码也适用于亮度变化changeColor传入相同的值就是亮度变化了。
看下各种滤镜的效果 最后
本章节我们学习了如何使用OpenGL ES对图片做各种滤镜效果我们发现通过修改GLSL就能实现很多种效果并且非常高效我们找到了OpenGL ES的用武之地。
其实对图片的滤镜效果有几十种上百种我们看下市面上的各种P图软件如醒图、美图秀秀等他们提供了丰富的滤镜效果。但再多的滤镜也是使用OpenGL ES框架编写GLSL来完成。而实现众多的滤镜效果已经和OpenGL ES没什么关系了而更多的是要熟悉图像处理的算法只要有算法就能通过GLSL实现。
OpenGL ES系列https://github.com/xiaozhi003/AndroidOpenGLDemo.git如果对你有帮助可以star下万分感谢^_^