【问题标题】:Android camera preview SurfaceTexture translation boundariesAndroid相机预览SurfaceTexture翻译边界
【发布时间】:2014-10-23 15:45:25
【问题描述】:

我正在开展一个项目,该项目需要我“平移”相机预览以找到一个小区域。我通过将预览渲染到 SurfaceTexture 并将变换应用于传递到顶点着色器的顶点来部分工作。用户看到并能够“平移”的“裁剪”区域为 1024x1024,相机预览尺寸为 1920x1080。

我遇到的问题本质上是找到预览的界限。我可以将顶点完全移出屏幕,它会继续移动。我尝试了几种策略来解决这个问题,但我没有任何运气。

我尝试的第一件事是计算形状顶点中的值,以使预览与视图齐平。在没有应用任何比例的情况下,形状顶点的范围应该是 [-1,1]。对于上下左右方向的以下顶点也是如此。但是,我通过反复试验发现右边缘的偏移量为 0.12。这是完全合乎逻辑的,因为相机预览比显示它的视图宽得多。我不确定我应该如何解释这一点以强制执行边界。

/* Initial position of the shape */
{ -1.0  1.0 
  -1.0 -1.0 
   1.0 -1.0 
   1.0  1.0 }

/* Right edge against the screen */
{    -1.12  1.0 
     -1.12 -1.0 
      0.88 -1.0 
      0.88  1.0  }

出于好奇,接下来我尝试使用 glReadPixel 获取屏幕边缘的像素列。我发现如果将形状从屏幕上平移出来,我得到的像素都是相等的。这一切都奏效了,直到我达到上面提到的偏移量。在 [-1,1] 有效地切断最后一部分之后,我拥有的像素都是相等的。这只是我用来试水的东西。

glReadPixel(1023, 0, 1, 1024);

鉴于我使用的是 openGL es 2.0,显然很难解释来自着色器的数据。为了尝试查看发生了什么,我编写了一个小实用函数来应用着色器中的转换并将它们打印出来,这就是上述顶点的来源。

有人对此有任何见解吗?我试图寻找任何可以为我指明正确方向的东西,但我什么也没找到。如果有任何有用的代码,请告诉我,如果可以,我会发布。

public void printFinalShapeCoords(float coords[]) {
    float shapeCoords[] = new float[8];
    for(int i = 0; i < coords.length; i+=2) {
        mScratchVector[0] = coords[i];
        mScratchVector[1] = coords[i+1];
        mScratchVector[2] = 0;
        mScratchVector[3] = 1;
        Matrix.multiplyMV(mTempVector, 0, mMVPMatrix, 0, mScratchVector, 0);
        shapeCoords[i] = mTempVector[0];
        shapeCoords[i+1] = mTempVector[1];
    }
    Log.e(TAG, "Final shape coords:\n"+Arrays.toString(shapeCoords));
}

顶点着色器:

                "uniform mat4 u_MVPMatrix;"+                /* 4x4 MVP matrix */
            "attribute vec4 vPosition;" +               /* Position vector */
            "attribute vec2 inputTextureCoordinate;" +  /* Texture coordinates */
            "varying vec2 textureCoordinate;" +         /* Texture coordinates that are passed to the fragment shader */
            "void main()" +
            "{"+
                "gl_Position = u_MVPMatrix*vPosition;"+ /* Multiply the MVP matrix and the position vector */
                "textureCoordinate = inputTextureCoordinate;" +
            "}";

片段着色器:

            "#extension GL_OES_EGL_image_external : require\n"+
            "precision mediump float;" +
            "varying vec2 textureCoordinate;\n" +
            "uniform samplerExternalOES s_texture;\n" +
            "void main() {" +
            "  gl_FragColor = texture2D( s_texture, textureCoordinate );\n" +
            "}";

编辑(2014 年 10 月 24 日下午 3:07 EST)

有评论提到我不太清楚我要完成什么,我想澄清一下。

基本上,我正在尝试显示相机预览的一部分,同时能够在按下按钮时查看剩余的预览。显示的部分为 1024x1024,而相机预览尺寸为 1920x1080。我要进行的行为的一个示例是在 Gallery 应用程序中。在查看图片时,用户可以“缩放”然后“遍历”图片的其余部分。我正在尝试这样做,但使用相机预览而不是静态图像。正如我之前提到的,我的缩放/平移工作正常,但我找不到停止平移的点。

【问题讨论】:

  • 你的MVP矩阵是你从getTransformMatrix得到的吗?
  • @mikkokoo 不,不是。我在每个绘制调用的纹理顶点上使用 getTransformMatrix 。我从该函数得到的矩阵几乎是一个单位矩阵,但不是 y 的正 1,而是负 1,它将相机预览翻转到正确的方向。 MVP 矩阵包含应用于形状顶点的其他变换。
  • 好的。如果您只是想将纹理blit 到视图(即没有3D 转换),您可以跳过矩阵并直接使用clip space 坐标作为顶点位置。然后移动纹理坐标以平移图像。不过,我认为我不太明白你想要做什么。
  • @mikkokoo 我编辑了问题以尝试澄清一下。

标签: android opengl-es android-camera opengl-es-2.0


【解决方案1】:

答案是您必须手动跟踪偏移和缩放(即在用户平移后强制偏移在特定边界内)。

我这样做的方式是直接使用clip space 坐标。因此,对于 1024x1024 视图和 1920x1080 纹理,您的顶点只针对 y [-1,1] 和针对 x [-1.77778,1.77778](然后比例 [1.0,1.0,1.0] 会淹没视图)。

从着色器中完全移除 MVP。

然后引入制服比例和偏移量。平移移动偏移量,缩放改变比例。

因此:

attribute mediump vec3 vertex;
attribute mediump vec2 texCoord;
varying mediump vec2 v_texCoord;
uniform mediump vec3 offset;
uniform mediump vec3 scale;
void main(){
 gl_Position=vec4((vertex-offset)*scale,1.0);
 v_texCoord=vec2(texCoord);
}

在 Java 中有一个健全性检查功能,可确保偏移始终在顶点边界内,记住要考虑比例。

【讨论】:

  • 这看起来很有希望;我今天应该可以试试这个然后回复你。谢谢
  • 抱歉耽搁了。我从着色器中删除了矩阵并添加了偏移/缩放制服,其效果与我对 MVP 矩阵的效果相同。既然我有了这个,我不确定我是否理解你所说的“让你的顶点是 y [-1,1] ...”是什么意思。我意识到这些范围是什么,但我不确定如何“执行”这些范围。视图似乎是“居中”的,因为它与除右侧之外的所有侧面的距离相等。是否需要计算视图边缘到纹理边缘的距离?
  • 这只是意味着你的顶点应该是[-1.77778,1],[-1.77778,-1],[1.77778,-1],[1.77778,1]。 IE。它们保持不变,然后通过偏移和比例控制显示的内容。顶点的所有纹理坐标应为 1 或 0。
  • 我需要使用投影矩阵来执行此操作还是只需将初始形状顶点设置为您上面列出的值?我尝试将它们设置为初始形状顶点,但它摆脱了纵横比。我不是要密集,我只是不确定如何准确地执行您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
相关资源
最近更新 更多