webgl 图像处理2---图像像素处理
2021-09-19 23:09
686 查看
webgl 图像处理
webgl 不仅仅可以用来进行图形可视化, 它还能进行图像处理
图像处理2---图像传输
之前已经进行了点和 uv 数据的传输
webgl 进行图形处理的第二步: 传输图片到 GPU
下图为传输图片并进行相应渲染的结果
对图像进行模糊处理, 并转换为数组输出
处理过程详解
-
加载图片
由于加载图片是异步方法, 因此很多内容都需要写在加载图片的回调函数内 - 在回调函数中进行传输图片操作
传输图片到 GPU
-
之前传输数据的步骤
创建缓存区
-
创建材质 Texture ( 对应前面第 1 步 )
查询当前像素的上下左右的颜色值并进行平均
-
当前节点的 uv 为 vUv, 是一个二维向量, 范围从 0-1
输出图像到数组中
// 将图片数据加载到 pixels 数组中 const pixels = new Uint8Array(200 * 200 *4); gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, pixels); console.log(pixels);
最后去得到一个 arrayBuffer 数组
下一阶段
当前阶段对图片进行像素颗粒的控制, 利用这个思路能实现大部分对图片的操作
下个阶段是输入一个数组, 在 GPU 中对数组进行计算, 最后得到相应的数值, 加速计算, 充分利用 GPU 并行计算的能力
代码实现
import Img from "./img/img1.jpg"; // 两种着色器 const VSHADER_SOURCE = ` attribute vec4 a_Position; attribute vec2 uv; varying vec2 vUv; void main(){ // 进行插值计算 vUv = uv; gl_Position = a_Position; } `; const FSHADER_SOURCE = ` // 片元着色器中一定要声明精度 precision mediump float; varying vec2 vUv; uniform sampler2D u_Texture; // 求平均 vec4 calculate(vec4 color, vec2 vUv){ vec4 tempColor = color; if(vUv.x != 0.0 && vUv.y != 0.0){ vec4 left = texture2D(u_Texture, floor(vUv * 200.0 + vec2(-1.0, 0.0)) / 200.0); vec4 right = texture2D( 56c u_Texture, floor(vUv * 200.0 + vec2(1.0, 0.0)) / 200.0); vec4 top = texture2D(u_Texture, floor(vUv * 200.0 + vec2(0.0, 1.0)) / 200.0); vec4 bottom = texture2D(u_Texture, floor(vUv * 200.0 + vec2(0.0, -1.0)) / 200.0); // tempColor.rg = 1.0 * (left.rg + right.rg + top.rg + tempColor.rg + bottom.rg) / 5.0; tempColor = 1.0 * (left + right + top + tempColor + bottom) / 5.0; } return tempColor; } void main(){ vec4 color = texture2D(u_Texture, vUv); color = calculate(color, vUv); gl_FragColor = color; } `; init(); function init() { const canvas = document.createElement("canvas"); canvas.width = 200; canvas.height = 200; document.body.appendChild(canvas); // 获取 gl 环境 const gl = canvas.getContext("webgl"); if (!gl) { console.log("Fail to init content"); return; } // webgl 程序 const programe = gl.createProgram(); // 初始化着色器 initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe); // 发送数据 sendData("a_Position", 2, [-1, 1, -1, -1, 1, -1, 1, 1], gl, programe); sendData("uv", 2, [0, 1, 0, 0, 1, 0, 1, 1], gl, programe); // 加载图片 loadImage(gl, programe); } // 初始化着色器 function initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE, programe) { // 创建 shader const vertexShader = gl.createShader(gl.VERTEX_SHADER); // 绑定资源 ad8 gl.shaderSource(vertexShader, VSHADER_SOURCE); // 编译着色器 gl.compileShader(vertexShader); const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER, FSHADER_SOURCE); gl.shaderSource(fragmentShader, FSHADER_SOURCE); gl.compileShader(fragmentShader); // 常规流程 gl.attachShader(programe, vertexShader); gl.attachShader(programe, fragmentShader); gl.linkProgram(programe); gl.useProgram(programe); } // 发送数据到 GPU function sendData(name, size, arr, gl, programe) { // 获取地址空间 const variate = gl.getAttribLocation(programe, name); if (variate < 0) { console.log(`Failed to get the location of ${name}`); return; } const variates = new Float32Array(arr); // 1. 创建缓存区 const buffer = gl.createBuffer(); if (!buffer) { console.log("Failed to create buffer"); } // 2. 绑定缓存区 gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // 3. 向缓冲区中添加数据 gl.bufferData(gl.ARRAY_BUFFER, variates, gl.STATIC_DRAW); // 4. 将缓冲区与 glsl 中变量绑定 gl.vertexAttribPointer(variate, size, gl.FLOAT, false, 0, 0); // 5. 开始传输 gl.enableVertexAttribArray(variate); } function loadImage(gl, programe){ // 初始化 Image const image = new Image(); // 通过 loader 加载图像路径 image.src = Img; // 设置回调函数 image.onload = ()=>{ const texture = gl.createTexture(); // y 轴反转 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // 激活 0 号纹理单元 gl.activeTexture(gl.TEXTURE0); // 绑定 texture gl.bindTexture(gl.TEXTURE_2D, texture); // 图像处理, 一定要有, 用来将图片宽高扩展到 2 的幂 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);// 配置纹理参数 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); // 配置图片 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); // 配置纹理图像 // 传输图片 const u_Texture = gl.getUniformLocation(programe, "u_Texure"); gl.uniform1i(u_Texture, 0); // 刷新颜色 gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清除 gl.clear(gl.COLOR_BUFFER_BIT); // 画图形 gl.drawArrays(gl.TRIANGLE_FAN, 0, 4); // 将图片数据加载到 pixels 数组中 const pixels = new Uint8Array(200 * 200 *4); gl.readPixels(0, 0, 200, 200, gl.RGBA, gl.UNSIGNED_BYTE, pixels); console.log(pixels);} }
相关文章推荐
- C#图像的灰度化处理:提取像素法介绍
- 山外多功能调试助手,摄像头。关于像素的理解,图像处理的理解
- Android图像处理之像素点处理效果--(5)
- c#图像处理入门(-bitmap类和图像像素值获取方法)
- Cimage类处理图像像素(数据)的3种方式
- 图像处理------基于像素的皮肤检测技术 分类: 视频图像处理 2015-07-24 09:56 28人阅读 评论(0) 收藏
- 图像处理基础(五)_图像像素中通道概念解析
- Python OpenCV处理图像之图像像素点操作
- **ANDROID**# 第七章图形与图像处理(静态处理) > Bitmap是有像素点构成的点阵图。 ------ ## 使用简单的图片 ---- * 通过Drawable对象进行访问。
- c#图像处理入门(-bitmap类和图像像素值获取方法)
- OpenCV-图像处理(22、像素重映射(cv::remap))
- 基于Python图像处理—像素操作
- Delphi图像处理 -- 图像像素结构与图像数据转换
- 图像处理------基于像素的皮肤检测技术
- c#图像处理入门(-bitmap类和图像像素值获取方法)
- vb.net 教程 5-13 图像处理之像素处理 2
- OpenCV中读取图像像素值 - [图像处理\OpenCV编程]
- java像素级图像处理与识别方法
- vb.net 教程 5-13 图像处理之像素处理 5
- c#图像处理入门(-bitmap类和图像像素值获取方法) .