如何使用 WebGL 进行实时视频处理( 二 )


gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, video);在着色器代码中读取纹理数据您可以通过 texture 的 2Dglsl 函数访问纹理的像素数据 。
当纹理坐标从(0,0)变为(1,1)时,图像会上下颠倒 。同时,我正处于水平镜像图像中(就像用相机自拍一样) 。
uniform sampler2D texture0;void main() {vec2 coord = 1.0 - gl_FragCoord.xy / vec2(width, height);gl_FragColor = texture2D(texture1, coord);}访问网络摄像头要从网络摄像头获取图像数据,我们可以使用 video 标签,并使用 getUserMediaAPI :
function accessWebcam(video) {return new Promise((resolve, reject) => {const mediaConstraints = { audio: false, video: {width: 1280,height: 720,brightness: {ideal: 2}}};navigator.mediaDevices.getUserMedia(mediaConstraints).then(mediaStream => {video.srcObject = mediaStream;video.setAttribute('playsinline', true);video.onloadedmetadata = https://www.isolves.com/it/rj/ysp/2020-09-02/(e) => {video.play();resolve(video);}}).catch(err => {reject(err);});});}// 使用说明:// const video = await accessWebcam(document.querySelector('video'));// or via promises:// accessWebcam(document.querySelector('video')).then(video => { ... });要访问网络摄像头,您可以使用 getUserMedia API 来访问网络摄像头,如上所述 。
提供后备图像如果用户阻止了对网络摄像头的访问,或者没有可用的网络摄像头,则可以提供一个备用图像供您使用 。
我也将 new Image() 中的 onload 操作包装成一个 promise。
function loadImage(url) {return new Promise((resolve, reject) => {const img = new Image();img.crossOrigin = 'Anonymous';img.src = https://www.isolves.com/it/rj/ysp/2020-09-02/url;img.onload = () => {resolve(img);};img.onerror = () => {reject(img);};});}合并全部操作为了使事情变得容易一些,我将常用的 WebGL 函数放入了我创建的一个小助手库 GLea 中 。
它初始化 WebGL 应用上下文,编译 WebGL 着色器代码,并为顶点着色器创建属性和缓冲区:
默认情况下,position 为顶点着色器提供一个属性,该属性带有一个缓冲区,该缓冲区包含 4 个 2D 坐标,覆盖整个屏幕上的 2 个三角形 。
import GLea from 'glea.js';const frag = ` ... `; // 片段着色器代码const vert = ` ... `; // 顶点着色器代码const glea = new GLea({shaders: [GLea.fragmentShader(frag),GLea.vertexShader(vert)]}).create();function loop(time = 0) {const { gl, width, height } = glea;glea.clear();glea.uniV('resolution', [width, height]);glea.uni('time', time * 1e-3);gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);requestAnimationFrame(loop);}window.addEventListener('resize', () => {glea.resize();});loop(0);结论基本上就是这样 。我希望您喜欢阅读本文,并对自己探索 WebGL 感到好奇 。我会在这里放一些资源 。





推荐阅读