OpenGLES:相机实时滤镜四宫格、九宫格

news2025/4/6 18:08:15

一.概述

今天继续OpenGLES的学习

今天在之前博文《OpenGLES:GLSurfaceView实现Android Camera预览》 的基础上,使用OpenGLES实现相机 四宫格滤镜九宫格滤镜

二.四宫格

先定义几个名词:

  • 之前博文中实现的相机普通预览叫:"大宫格"
  • 现在要实现的是:"四宫格"+"滤镜"
  • 四宫格的每一个小宫格叫:"小宫格"
  • 小宫格区域内的点记为:(min_x, min_y)
  • 小宫格原点记为:(min_origin_x, min_origin_y)
  • 大宫格区域内的点记为:(max_x, max_y)

大宫格原点是(0,0),不用专门标记

先看怎么实现四宫格,再看怎样+滤镜

小宫格(min_x, min_y)是从属于大宫格(max_x, max_y)的,它只是(max_x, max_y)的一个1/4子区域
我们要做的就是怎么把(min_x, min_y)通过换算对应到(max_x, max_y)

通过图示不难看出:

1.大宫格相当于小宫格沿x、y轴反方向移动(min_origin_x, min_origin_y)到(0,,0),再将长、宽乘以2
也可以反向认为:
2.小宫格相当于大宫格的长、宽都除以2,再沿x、y轴正向移动到(min_origin_x,min_origin_y)

"右上角小宫格"例:

1.大宫格相当于右上角小宫格沿x,y轴反方向移动(0.5,0.5)到(0,0),再将长、宽都放大2倍

或者

2. 右上角小宫格相当于大宫格长、宽都缩小1/2,再沿x、y轴正方向移动到(0.5,0.5)

我们要做的是怎么把纹理采样坐标中的部分坐标(小宫格)对应到全部坐标(大宫格)

所以我们要找到的是上述"1."的对应关系,反向的"2."是为了更形象的理解过程

按照这种方法,不管多复杂的宫格分割,只要推导出小宫格通过怎样的平移和缩放能够与"大宫格"重叠,就能找到对应关系

所以"小宫格"换算对应到"大宫格"的公式:

max_x = (min_x - min_origin_x) *2
max_y = (min_y - min_origin_y) *2

(min_origin_x, min_origin_y)可以再进一步通过要实现的"几宫格""几"进行公式化,这个不难,就不推导了。

三.滤镜

在片段着色器中,通过纹理采样器纹理坐标创建出纹理

创建的纹理其实就是要赋值给内建变量的颜色值向量

这也是为什么要通过纹理采样器纹理坐标,相当于纹理采样器根据纹理坐标获取这个坐标点的颜色值,所有颜色值形成一张五彩缤纷的图,就是纹理

通过颜色向量可以拿到色值的RGB分量

那么就可以对颜色做出各种"滤镜"效果了

如下是黑白滤镜代码:

//黑白
void blackAndWhite(inout vec4 color){
    float threshold = 0.5;
    float mean = (color.r + color.g + color.b) / 3.0;
    color.r = color.g = color.b = mean >= threshold ? 1.0 : 0.0;
}

直接通过代码字面就能理解了:

纹理坐标点采样到的颜色值的(r、g、b)三个分量,如果平均值>0.5,就赋值为白,反之为黑。

如下就是最终实现四宫格的黑白、灰度、反向、原图实时滤镜着色器代码:

看字面都很好理解,不一一说明了

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec2 texCoord;//纹理坐标,图片当中的坐标点
out vec4 outColor;

uniform samplerExternalOES s_texture;//图片,采样器

//黑白
void blackAndWhite(inout vec4 color){
    float threshold = 0.5;
    float mean = (color.r + color.g + color.b) / 3.0;
    color.r = color.g = color.b = mean >= threshold ? 1.0 : 0.0;
}

//灰度
void grey(inout vec4 color){
    float weightMean = color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
    color.r = color.g = color.b = weightMean;
}

//反向
void reverse(inout vec4 color){
    color.r = 1.0 - color.r;
    color.g = 1.0 - color.g;
    color.b = 1.0 - color.b;
}

void main(){
    float x = texCoord.x;
    float y = texCoord.y;

    //四宫格滤镜
    if (x <= 0.5 && y <= 0.5){
        x = x * 2.0;
        y = y * 2.0;
        outColor = texture(s_texture, vec2(x, y));
        reverse(outColor);
    } else if (x <= 0.5 && y >= 0.5){
        x = x * 2.0;
        y = (y-0.5) * 2.0;
        outColor = texture(s_texture, vec2(x, y));
        blackAndWhite(outColor);
    } else if (x>0.5 &&  y > 0.5){
        x = (x-0.5) * 2.0;
        y = (y-0.5) * 2.0;
        outColor = texture(s_texture, vec2(x, y));
        grey(outColor);
    } else if (x>0.5 &&  y < 0.5){
        x = (x-0.5) * 2.0;
        y = y * 2.0;
        outColor = texture(s_texture, vec2(x, y));
    }
}

实现效果:

 

四.九宫格滤镜

如果你跟着博文一直学习到这里,并且自己动手实现了四宫格滤镜,那么九宫格滤镜也只是顺理成章的事了。

九宫格示例代码中,我没有逐个宫格计算实现,而是通过x,y的等分范围来实现

所以也没有逐个添加滤镜效果,重点在于九宫格的实现

前文中也提到过,只要找到了小宫格大宫格的对应关系,也完全可以根据"几宫格""几",将着色器代码进一步精简,用循环语句来划分宫格。

理解透了原理就万变不离其宗了,代码实现只是形式

如下是九宫格着色器代码:

#version 300 es
#extension GL_OES_EGL_image_external_essl3 : require
precision mediump float;

in vec2 texCoord;//纹理坐标,图片当中的坐标点
out vec4 outColor;

uniform samplerExternalOES s_texture;//图片,采样器

void main(){
    float x = texCoord.x;
    float y = texCoord.y;

    //九宫格滤镜
    float x = texCoord.x;
    float y = texCoord.y;

    if (x < 1.0 / 3.0) {
        x = x * 3.0;
    } else if (x < 2.0 / 3.0) {
        x = (x - 1.0 / 3.0) * 3.0;
    } else {
        x = (x - 2.0 / 3.0) * 3.0;
    }
    if (y <= 1.0 / 3.0) {
        y = y * 3.0;
    } else if (y < 2.0 / 3.0) {
        y = (y - 1.0 / 3.0) * 3.0;
    } else {
        y = (y - 2.0 / 3.0) * 3.0;
    }

    outColor = texture(s_texture, vec2(x, y));
}

实现效果: 

五.结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/663460.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【人工智能】“AI + 算力 = 最强龙头”,你怎么看?

文章目录 一、AI 与算力相辅相成1.1 AI 和算力的概念1.2 AI 和算力的应用领域1.3 AI 需要算力的支持1.4 AI 和算力的结合带来的巨大价值1.4.1 人脸识别1.4.2 语音识别1.4.3 自动驾驶1.4.4 医疗诊断1.4.5 自然语言处理 二、AI算力催生“最强龙头”2.1 “最强龙头”的概念2.2 AI …

Unity核心4——SpriteShape

Sprite Shape 是精灵形状的意思&#xff0c;它主要是方便我们以节约美术资源为前提&#xff0c;制作 2D 游戏场景地形或者背景的 ​ 在 Window --> Package Manager 中搜索 2D&#xff0c;选择 2D Sprite Shape&#xff0c;导入项目 一、Sprite Shape Profile 精灵形状概述文…

FPGA基础知识-用户自定义原语

目录 学习目标 学习内容 1.UDP的组成 2.UDP定义规则 3.表示组合逻辑的UDP 4.表示时序逻辑的UDP 5.UDP表中的缩写符号 6.UDP设计指南 学习时间 学习总结 学习目标&#xff1a; 提示&#xff1a;这里可以添加学习目标 理解编写UDP的规则,明白UDP的各个组成部分。 学…

设计师常用的网页设计素材网站大全

设计师不仅需要源源不断的灵感&#xff0c;还需要与时俱进的网页设计素材。 本文推荐4个非常不错的设计素材网站 即时设计资源社区 ​即时设计资源社区是国内优秀的网页设计素材网站&#xff0c;内置阿里、字节、腾讯、京东、谷歌、华为等设计系统&#xff0c;超过3000UI组件…

DDoS攻击导致Azure和Outlook中断

微软已经证实&#xff0c;最近Azure、Outlook和OneDrive门户网站的中断是由于针对该公司服务的第7层DDoS攻击造成的。 这些攻击是由微软追踪到的一个名为Storm-1359的攻击组织造成的&#xff0c;他们自称是匿名苏丹。 故障发生在6月初&#xff0c;Outlook.com的网络门户在6月…

分布式配置中心Apollo中Namespace的类型整理

Namespace的类型 Namespace类型有三种&#xff1a; 【1】私有类型 【2】公共类型 【3】关联类型&#xff08;继承类型&#xff09; &#xff08;1&#xff09;私有类型 私有类型的Namespace具有private权限。例如上文提到的“application” Namespace就是私有类型。 &…

【计算机网络】运输层端口号、复用与分用

1、复用和分用 2.端口号 3.举例 4.详细学习视频 https://www.bilibili.com/video/BV1c4411d7jb?p58&vd_source621b166d35a3636b23f3c4d270272c53

WSL子系统启动报错 Wsl/Service/CreateInstance/CreateVm/HCS_E_SERVICE_NOT_AVAILABLE

今天琢磨着WindowsLinux子系统研究研究新东西&#xff0c;结果当我启动WSL时却出现了下面的提示&#xff1a; WSL启动报错 由于未安装所需的特性&#xff0c;无法启动操作。 Error code: Wsl/Service/CreateInstance/CreateVm/HCS_E_SERVICE_NOT_AVAILABLE问题排查 于是分析…

Audio API 实现音频播放器

市面上实现音频播放器的库有很多&#xff0c;比如wavesurfer.js、howler.js等等&#xff0c;但是都不支持大音频文件处理&#xff0c;100多M的文件就有可能导致程序崩溃。总之和我目前的需求不太符合&#xff0c;所以打算自己实现一个音频播放器&#xff0c;这样不管什么需求 在…

软件工程是否迎来iPhone时刻?

“软件工程是否迎来iPhone时刻&#xff1f;” 是2023K全球软件研发行业创新峰会上海站主会场的Panel discussion的主题&#xff0c;出场的几位嘉宾给出了不同的答案&#xff0c;其中有两位嘉宾给出了“No”&#xff0c;一位给出了“塞班时刻”&#xff08;后来给我朋友圈投票是…

设计模式—“状态变化”

在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定?"状态变化"模式为这一问题提供了解决方案。 典型模式有:Memento、State 一、State 动机 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而…

18-BOM对象

一、是什么 &#x1f355;&#x1f355;&#x1f355;BOM (Browser Object Model)&#xff0c;浏览器对象模型&#xff0c;提供了独立于内容与浏览器窗口进行交互的对象 其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退&#xff0c;前进&#xff0c;刷新&#xff0…

SSM幼儿园管理系统的设计与实现-计算机毕设 附源码86673

SSM幼儿园管理系统的设计与实现 摘 要 21世纪时信息化的时代&#xff0c;几乎任何一个行业都离不开计算机&#xff0c;将计算机运用于幼儿管理系统也是十分常见的。过去使用手工的管理方式对幼儿园进行管理&#xff0c;造成了管理繁琐、难以维护等问题&#xff0c;如今使用计算…

搜索表单的触发方式

1、按键盘触发 配套监听 _keydownHandler: function (event) { // 获取表单数据 let formValue this.$[frm-mach-break].serializeMyForm(); let params { machineName: formValue.mach_id }; this.requestAjax(ajx-view-mach-break, params); }, onKeypress: function ({ ke…

抖音seo账号矩阵系统源码sign解密.技术

抖音SEO矩阵系统源码是一种用于优化抖音视频内容的工具&#xff0c;可以帮助用户提高抖音视频的搜索排名和流量&#xff0c;从而增加视频曝光和转化率。该系统包括两部分&#xff0c;即数据收集和分析模块以及SEO策略和实施模块。 返回示例 错误&#xff1a; { "ec…

搜索算法(五) DFS BFS 练习题

练习题 1.力扣https://leetcode.cn/problems/surrounded-regions/这题和417类似&#xff0c;都是从边界朝内部搜索&#xff0c;417用的是DFS&#xff0c;这里为了练习&#xff0c;就用BFS。 首先从四条边界得到‘O’的坐标&#xff0c;加入队列。接着一层一层搜索&#xff0c…

11个AI绘画软件大全,赶紧收藏

随着人工智能技术的不断发展&#xff0c;越来越多的AI绘画软件应运而生。AI绘画软件利用人工智能技术&#xff0c;通过计算机自动生成或辅助生成艺术作品。 AI绘画软件通常集深度学习、计算机视觉、自然语言处理等技术于一体&#xff0c;可以模拟人类的创作过程&#xff0c;生…

带你详细了解Redis事务锁机制-加实列演示-加连接池-包括解决遗留问题-下

Redis_事务_锁机制_秒杀 连接池技术 连接池介绍 1、节省每次连接redis 服务带来的消耗&#xff0c;把连接好的实例反复利用。 2、链接池参数 MaxTotal&#xff1a;控制一个pool 可分配多少个jedis 实例&#xff0c;通过pool.getResource()来获取&#xff1b;如果赋值为-1&…

.NetCore gRpc 客户端与服务端的单工通信Demo

文章目录 .NetCore gRpc 客户端与服务端的单工通信Demo服务端方式一方式二 客户端proto协议文件syntax "proto3";import "google/protobuf/empty.proto";serviceproto3与.netCore 的类型对应日期和时间可为 null 的类型字节小数为 Protobuf 创建自定义 de…

<Linux开发>驱动开发 -Linux MISC 驱动

&#xff1c;Linux开发&#xff1e;驱动开发 -Linux MISC 驱动 交叉编译环境搭建&#xff1a; &#xff1c;Linux开发&#xff1e; linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下&#xff1a; &#xff1c;Linux开发&#xff1e; -之-系统移植 uboot移植过程详细记…