You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android OpenGLES中保持宽高比将CameraX纹理Upscale至视口的技术问题

在GLSurfaceView着色器中保持几何体尺寸不变,实现相机纹理的宽高比适配Upscale

解决思路:不缩放几何体顶点,而是通过调整纹理UV坐标实现相机帧的宽高比适配,同时让几何体保持全屏尺寸。

1. Java层计算UV变换参数

在渲染循环中,根据纹理和视口的宽高比计算UV的缩放因子与偏移量:

float imgAspect = (float) cameraFrameTexture.getWidth() / cameraFrameTexture.getHeight();
float viewAspect = (float) GLRenderer.rendererWidth / GLRenderer.rendererHeight;

float scaleUVX = 1.0f;
float scaleUVY = 1.0f;
float offsetUVX = 0.0f;
float offsetUVY = 0.0f;

if (imgAspect > viewAspect) {
    // 图像宽于视口:垂直方向缩放,上下留黑居中
    scaleUVY = viewAspect / imgAspect;
    offsetUVY = (1.0f - scaleUVY) / 2.0f;
} else {
    // 图像高于视口:水平方向缩放,左右留黑居中
    scaleUVX = imgAspect / viewAspect;
    offsetUVX = (1.0f - scaleUVX) / 2.0f;
}

// 传递参数到着色器
int scaleLoc = GLES20.glGetUniformLocation(yourProgramId, "uScaleUV");
int offsetLoc = GLES20.glGetUniformLocation(yourProgramId, "uOffsetUV");
GLES20.glUniform2f(scaleLoc, scaleUVX, scaleUVY);
GLES20.glUniform2f(offsetLoc, offsetUVX, offsetUVY);

2. 顶点着色器(仅处理UV变换)

保持顶点位置不变,只对UV坐标做适配变换,确保纹理采样区域正确:

uniform mat4 uMVPMatrix;
uniform vec2 uScaleUV;
uniform vec2 uOffsetUV;
attribute vec3 aPosition;
attribute vec2 aTexCoords;

varying vec2 vTexCoords;

void main() {
    // 几何体顶点位置保持不变,依然占满视口
    gl_Position = uMVPMatrix * vec4(aPosition.xyz, 1.0);
    
    // 计算适配后的UV坐标
    vTexCoords = aTexCoords * uScaleUV + uOffsetUV;
}

3. 片段着色器(正常采样)

使用调整后的UV坐标采样纹理即可:

precision mediump float;
uniform sampler2D uCameraTexture;
varying vec2 vTexCoords;

void main() {
    gl_FragColor = texture2D(uCameraTexture, vTexCoords);
}

重要说明

  • 原方案问题:你之前的代码是缩放顶点位置,导致几何体缩小来适配纹理比例;新方案保持几何体全屏,通过调整纹理采样范围实现比例适配,完全满足需求。
  • 多着色器适配:该UV变换逻辑独立于顶点变换矩阵,其他需要相机纹理的着色器只需传入相同的uScaleUV和uOffsetUV参数即可,不会干扰原有矩阵功能。
  • 性能优势:GPU层面的UV变换是并行处理,完全适配实时相机流的性能要求,避免了Bitmap/Canvas方案的CPU耗时问题。

内容的提问来源于stack exchange,提问作者Ashish11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:05:14