通过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日

相关文章

  • Win11更新后无法调节亮度怎么办 Win11亮度条消的解决办法

    下面是详细的攻略: 问题描述 在升级到Win11后,有些用户发现无法调节屏幕亮度的问题,甚至在屏幕亮度条消失了。这给用户带来了很大的不便,因为调节屏幕亮度是非常重要的。接下来,我将提供一些Win11亮度条消失的解决办法。 解决办法 1. 通过设备管理器更新显卡驱动程序 有时,屏幕亮度条消失的原因是因为显卡驱动程序过时或损坏。在这种情况下,我们可以通过设备管理…

    other 2023年6月27日
    00
  • Android不规则图像填充颜色小游戏

    Android不规则图像填充颜色小游戏攻略 游戏简介 Android不规则图像填充颜色小游戏是一款有趣的游戏,玩家需要根据给定的不规则图像,选择合适的颜色进行填充,以完成图像的填色任务。 游戏攻略 步骤1:了解游戏规则 在开始游戏之前,首先需要了解游戏的规则。通常,游戏会提供一个不规则的图像,玩家需要选择合适的颜色填充图像中的空白区域。游戏可能会限制填充的颜…

    other 2023年8月21日
    00
  • 移植busybox构建最小根文件系统的步骤详解

    下面是关于移植busybox构建最小根文件系统的步骤详解: 1. 安装交叉编译工具链 首先,我们需要安装交叉编译工具链,以便于在本机上生成可在目标设备上运行的二进制代码。具体操作步骤可能因系统而异,可以根据自己的系统情况去进行对应操作。以Ubuntu系统为例,可以通过以下命令安装arm-linux-gnueabi交叉编译工具链: sudo apt-get i…

    other 2023年6月27日
    00
  • webpack安装

    webpack安装 webpack是一个现代JavaScript应用程序的静态模块打包器。本文将提供一个完整的攻略,介绍如何安装webpack,并供两个示例说明。 安装Node.js 在安装webpack之前,需要先安装Node.js。可以从官网下载安包,或使用包管理器进行安装。 安装 可以使用以下命令安装webpack: npm install webpa…

    other 2023年5月8日
    00
  • IDEA如何添加配置文件到classpath中

    IDEA是一款常用的Java集成开发环境,可以进行Java编码、调试、构建等操作。要将配置文件添加到classpath中,可以按照以下步骤进行: 打开IDEA,并打开想要添加配置文件的项目。 在项目中选择要添加的配置文件,右键点击并选择“Mark Directory as”->“Resources Root”。这样会将该目录标记为资源目录,让IDEA知…

    other 2023年6月25日
    00
  • 一条命令重启所有已停止的docker容器操作

    要重启所有已停止的 Docker 容器,可以使用以下命令: docker container start $(docker container ls -aq) 该命令的原理是使用 docker container ls -aq 列出所有容器的 ID,包括已停止的。然后再使用 docker container start 命令将其全部启动。这种方式的好处在于,…

    other 2023年6月27日
    00
  • mysql的union用法

    MySQL的UNION用法 简介 MySQL中的UNION是一种合并两个或多个SELECT语句结果集的方式。这些SELECT语句可以来自同一张表,也可以来自不同的表。UNION操作会自动去重,只返回不同的记录。 语法 UNION语法如下: SELECT column_name(s) FROM table1 UNION [ALL | DISTINCT] SEL…

    其他 2023年3月28日
    00
  • 利用shell编程实现DOS风格的Linux命令行

    利用shell编程实现DOS风格的Linux命令行 在本文中,我们将介绍如何使用shell编程实现DOS风格的Linux命令行。通过这种方式,我们可以使用类似于DOS的命令行界面来操作Linux系统。 我们可以将这个功能实现为一个脚本,然后通过将脚本添加到PATH环境变量中,使其能够在系统任何位置被执行。 以下是实现该功能的步骤: 1. 创建一个脚本 首先,…

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