通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸

实现视频缩放的基本思路是通过改变渲染纹理的顶点坐标和纹理坐标实现,其中OpenGL ES混合模式是一种可以较好地适应不同尺寸的方法。

具体实现方法如下:

  1. 初始化OpenGL ES环境,通过GLSurfaceView.Renderer的回调函数onSurfaceCreated实现。
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // 初始化OpenGL环境
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    GLES20.glEnable(GLES20.GL_TEXTURE_2D);
    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
    GLES20.glDisable(GLES20.GL_DEPTH_TEST);
}
  1. 在每次视频图像被更新时,将纹理数据绑定到OpenGL ES纹理对象上,并更新顶点坐标和纹理坐标。在GLSurfaceView.Renderer的回调函数onDrawFrame实现。
@Override
public void onDrawFrame(GL10 gl) {
    // 清空屏幕
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    // 更新纹理数据
    surfaceTexture.updateTexImage();
    // 更新顶点坐标和纹理坐标
    float[] vertexCoords = {...};
    float[] textureCoords = {...};
    // 绘制纹理
    GLES20.glUseProgram(program);
    GLES20.glEnableVertexAttribArray(aPositionLocation);
    GLES20.glVertexAttribPointer(aPositionLocation, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);
    GLES20.glEnableVertexAttribArray(aTextureCoordLocation);
    GLES20.glVertexAttribPointer(aTextureCoordLocation, COORDS_PER_TEXTURE, GLES20.GL_FLOAT, false, textureStride, textureBuffer);
    GLES20.glUniformMatrix4fv(uMVPMatrixLocation, 1, false, mvpMatrix, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture[0]);
    GLES20.glUniform1i(uTextureLocation, 0);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, vertexCount);
    // 解绑定纹理
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
}

可以看到,通过使用混合模式GLES20.GL_BLEND并设置混合函数GLES20.GL_SRC_ALPHA和GLES20.GL_ONE_MINUS_SRC_ALPHA,可以实现更加自然的缩放效果,避免图像出现锯齿和失真现象。

下面是两个示例:

示例1:将视频缓冲区填充整个GLSurfaceView区域

顶点坐标和纹理坐标定义如下:

private static final float[] FULL_RECTANGLE_VERTEX_COORDS = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f, 1.0f,
        1.0f, 1.0f,
};

private static final float[] FULL_RECTANGLE_TEXTURE_COORDS = {
        0.0f, 0.0f,
        1.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 1.0f,
};

顶点坐标和纹理坐标填充整个GLSurfaceView区域,使用混合模式GLES20.GL_BLEND,并设置混合函数GLES20.GL_SRC_ALPHA和GLES20.GL_ONE_MINUS_SRC_ALPHA。

示例2:将视频缓冲区按照宽高比例缩放

顶点坐标和纹理坐标定义如下:

private static final float[] CROP_RECTANGLE_VERTEX_COORDS = {
        -1.0f, -aspectRatio,
        1.0f, -aspectRatio,
        -1.0f, aspectRatio,
        1.0f, aspectRatio,
};

private static final float[] CROP_RECTANGLE_TEXTURE_COORDS = {
        0.0f, 1 - texAspectRatio,
        1.0f, 1 - texAspectRatio,
        0.0f, 1.0f - (1 - texAspectRatio),
        1.0f, 1.0f - (1 - texAspectRatio),
};

其中,aspectRatio为GLSurfaceView的宽高比,texAspectRatio为视频缓冲区的宽高比。可以看到,在顶点坐标和纹理坐标中,通过相除和相减的方式,实现了缩放的效果。同样使用混合模式GLES20.GL_BLEND,并设置混合函数GLES20.GL_SRC_ALPHA和GLES20.GL_ONE_MINUS_SRC_ALPHA。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通过OpenGL ES混合模式缩放视频缓冲区来适应显示尺寸 - Python技术站

(0)
上一篇 2023年6月20日
下一篇 2023年6月20日

相关文章

  • 详解javascript中offsetleft属性的用法(转)

    详解javascript中offsetLeft属性的用法(转) 在前端开发中,我们经常需要获取页面元素在文档流中的位置信息。其中,offsetLeft属性可用于获取某个 HTML 元素相对与其父元素的左侧偏移量(即元素左边缘与其父元素左边缘之间的距离),并且不考虑边框宽度。本文将详解javascript中offsetLeft属性的用法,为大家讲解如何正确地使…

    其他 2023年3月28日
    00
  • Java Lambda表达式的方法引用和构造器引用实例分析

    Java Lambda表达式的方法引用和构造器引用实例分析 1. 方法引用(Method Reference)的概念 方法引用是Lambda表达式的一种简化形式,它允许我们直接通过方法的名称来引用已经存在的方法。 2. 方法引用的用法 方法引用可以分为四种不同的形式: 2.1 指向静态方法的方法引用 语法:类名::静态方法名 示例: import java.…

    other 2023年6月28日
    00
  • intelcpu命名规则的简略解析

    Intel CPU命名规则的完整攻略 Intel CPU是计算机中常用的处理器,其命名规则是由Intel公司制定的。本文将介绍Intel CPU命名规则的完整攻略,包括两个示例说明。 命名规则 Intel CPU的命名规则通常由一个字母和一组数字组成。其中,字母表示处理器系列,数字表示处理器型号和性能等级。 字母表示处理器系列 CPU的字母表示处理器系列,常…

    other 2023年5月9日
    00
  • 详解Linux系统中的进程初始化配置文件inittab

    下面是关于“详解Linux系统中的进程初始化配置文件inittab”的完整攻略。 什么是inittab 在Linux系统中,inittab是负责系统启动时加载和执行系统级别初始化进程的配置文件。在Linux的进程初始化过程中,inittab的作用十分关键。inittab文件通常位于/etc/inittab这个目录中。这个文件可以通过编辑来更改进程的初始化顺序…

    other 2023年6月20日
    00
  • 完全了解php的callable

    以下是关于“完全了解PHP的callable”的完整攻略,过程中包含两个示例。 背景 在PHP中,callable是一种特殊的数据类型,用于表示可以被调用的函数或方法。在使用callable时,我们需要了解其基本语法和用法,以便正确地使用它。 基本原理 在PHP中,callable是一种特殊的数据类型,用于表示可以被调用的函数或方法。callable可以用于…

    other 2023年5月9日
    00
  • latex使用markdown

    LaTeX使用Markdown LaTeX和Markdown都是文本编辑器,但它们的设计目标和应用场景有所不同。Markdown更加注重轻量级和易用性,用于快速、便捷地书写和分享文本;而LaTeX则致力于高质量的排版,适用于科学、技术和学术领域的论文、书籍和报告等文档。然而,通过Markdown可以轻松地写出LaTeX表达式,从而将Markdown和LaTe…

    其他 2023年3月28日
    00
  • js实现加载页面就自动触发超链接的示例

    实现加载页面就自动触发超链接的功能,可以使用JS的自动点击事件(click())实现。具体可以分为以下两条示例。 示例一 下面是执行代码函数: window.onload = function() { document.getElementById(‘link’).click(); } 在 HTML 页面中加入超链接(如下所示): <a id=&quo…

    other 2023年6月25日
    00
  • gradle插件版本和gradle版本对应关系

    以下是gradle插件版本和gradle版本对应关系的完整攻略: Gradle插件版本和Gradle版本之间有一定的对应关系。不同的Gradle插件版本需要不同的Gradle版本才能正常工作。以下是Gradle插件版本和Gradle版本的对应关系: Gradle插件版本 Gradle版本 1.0.0 – 1.1.x 1.12 – 2.3 1.2.0 – 1.…

    other 2023年5月8日
    00
合作推广
合作推广
分享本页
返回顶部