当前位置: 首页 > 知识库问答 >
问题:

绘制前裁剪GLES纹理

逄宁
2023-03-14

我正在使用SurfaceView通过GLES将相机预览渲染到屏幕上。是否可以在下面的方法中裁剪纹理,然后再进行渲染?我想裁剪一个16:9的纹理,在屏幕上显示为4:3。

public void drawFrame(int width, int height, float sourceAspectRatio, float targetAspectRatio, boolean flipHorizontally, boolean flipVertically) {

    //Aspect ratio correction. Source Aspect ratio is taken from Camera.Parameters.getPictureSize()
    //assuming that value is the native resolution of the camera. Sometimes the native camera aspect ratio
    //doesn't match the display's aspect ratio.
    float scaleX, scaleY;
    if (sourceAspectRatio >= targetAspectRatio) {
        scaleX = sourceAspectRatio/targetAspectRatio;
        scaleY = 1;
    } else {
        scaleX = 1;
        scaleY = targetAspectRatio/sourceAspectRatio;
    }

    if (flipHorizontally) scaleX = -scaleX;
    if (flipVertically) scaleY = -scaleY;

    checkGlError("onDrawFrame start");
    mSurfaceTexture.getTransformMatrix(mSTMatrix);

    GLES20.glViewport(0,0,width,height);

    GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    GLES20.glUseProgram(mProgram);
    checkGlError("glUseProgram");

    /**
     * Explanation of double binding: http://stackoverflow.com/questions/20386515/glsurfaceview-framerate-issues-on-nexus-5
     *
     * I was able to replicate the behavior, and my GL wizard office-mate figured out the problem.
     * Basically, one of the EGL contexts isn't noticing that the texture contents have changed, so it keeps rendering older data.
     * We think it's getting occasional updates because it has a set of buffers that it cycles through,
     * so eventually it re-uses the buffer you're looking at.
     * I was able to fix the problem in my code by updating the texture renderer class, changing this:
     *
     * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID)
     *
     * to this
     *
     * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
     * GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
     *
     * The un-bind and re-bind causes the driver to pick up the right buffer.
     */
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
    GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maPosition");
    GLES20.glEnableVertexAttribArray(maPositionHandle);
    checkGlError("glEnableVertexAttribArray maPositionHandle");

    mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
    GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
    checkGlError("glVertexAttribPointer maTextureHandle");
    GLES20.glEnableVertexAttribArray(maTextureHandle);
    checkGlError("glEnableVertexAttribArray maTextureHandle");
    Matrix.setIdentityM(mMVPMatrix, 0);
    mMVPMatrix[0] = scaleX;
    mMVPMatrix[5] = scaleY;
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
    GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);

    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    checkGlError("glDrawArrays");

    GLES20.glDisableVertexAttribArray(maTextureHandle);
    GLES20.glDisableVertexAttribArray(maPositionHandle);
    GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, 0);
    GLES20.glUseProgram(0);
}

共有1个答案

凌黎明
2023-03-14

只需改变你的纹理坐标(选择你想要在屏幕上出现的东西),和你的顶点坐标(决定你在屏幕上画的位置)。

 类似资料:
  • 裁剪区域clip() 使用Canvas绘制图像的时候,我们经常会想要只保留图像的一部分,这是我们可以使用canvas API再带的图像裁剪功能来实现这一想法。 Canvas API的图像裁剪功能是指,在画布内使用路径,只绘制该路径内所包含区域的图像,不绘制路径外的图像。这有点像Flash中的图层遮罩。 使用图形上下文的不带参数的clip()方法来实现Canvas的图像裁剪功能。该方法使用路径来对C

  • 问题内容: 我通过android开发实现了我的目标,如该链接所示:[从Android中的位图裁剪圆形区域,](http://codingdict.com/questions/148437 但是 如何 使用libGDX框架实现呢?我尝试与我合作,但没有成功。 任何人都可以帮助我实现这一目标。 问题答案: 我不知道是否有更简单的方法,但是我提出了一种使用遮罩并将遮罩与原始像素图合并为结果像素图的方法。

  • 我目前正在尝试开发一个Android上的视频播放器,但是在颜色格式上却很纠结。 上下文:我通过MediaExtractor/MediaCodec的标准组合来提取和解码视频。因为我需要提取的帧作为OpenGLES纹理(RGB)可用,所以我设置了解码器(MediaCodec),以便它通过SurfaceTexture提供外部GLES纹理(GL_TEXTURE_EXTERNAL_OES)。我知道我的HW解

  • 我试图在从图库中选择图像后使用intent来裁剪图像。以下是我的代码片段 在这里,我使用PICK_IMAGE_REQUEST意图句柄调用上面的代码段 由于我在裁剪后使用了相同的意图,即PICK_IMAGE_REQUEST,可能会出现什么问题

  • 问题内容: 我正在尝试裁剪图像,然后将裁剪后的图像粘贴到另一个图像的中心。理想情况下,我希望裁切后的图像小于粘贴的图像,以便在粘贴的图像周围有一个边框,但我不知道这样是否可行。 这是我尝试过的方法(以及由此产生的错误消息): 我可以看到“区域”的大小已设为(0,0),但我不明白为什么。 任何对此的帮助将非常感谢 问题答案: 裁剪方法的PIL文档指出: 返回当前图像的矩形区域。该框是一个四元组,定义

  • 裁剪节点 成员变量 变量 类型 名称 备注 clipRegion number 裁剪区域 无 enableClip boolean 是否开启裁剪 默认true 方法 构造函数 new BK.ClipRectNode(x,y,w,h) 参数 类型 名称 备注 x number 裁剪区域x坐标 y number 裁剪区域y坐标 width number 裁剪区域宽 height number 裁剪区域