在Android OpenGL ES中将2D纹理保存为png

4

我是一个新手,正在学习在Android中使用OpenGL ES。但是现在,我需要使用OpenGL ES 2.0来进行一些照片编辑。我在Android 4.1.2中找到了示例代码"Hello-effect",它完成了编辑照片并将其呈现在窗口中的工作。但是现在,我还需要将编辑后的照片保存到本地位图中。我认为可能有一些方法可以直接从纹理中获取数据,但我找到的唯一方法是glReadPixels(...)。因此,我尝试使用它:

第一次测试:

  1. 我使用GLSurfaceView来显示已通过android.media.effect API编辑的照片。
  2. 我在与GLSurfaceView相同的布局中添加了一个按钮。
  3. 当单击按钮时,我调用glReadPixels(...)来获取照片数据。 但是在步骤3中,我只得到了按钮的数据。
我猜想,在我点击按钮时,窗口的帧缓冲区已被按钮的内容替换。

第二次测试:

  1. 我创建了一个FBO来保存编辑后的照片,并使用glReadPixels(...)来获取照片数据,但结果是一张黑色的图片。

代码如下:

public void renderTextureOffscreen (int texId) {
    // Bind default FBO
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, offScreenFrameBuffer[0]); 
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,GLES20.GL_COLOR_ATTACHMENT0,GLES20.GL_TEXTURE_2D, texId , 0);

    int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
    if(status == GLES20.GL_FRAMEBUFFER_COMPLETE)
    {
        // Set viewport
        GLES20.glViewport(0, 0, mViewWidth, mViewHeight);
        GLToolbox.checkGlError("glViewport");

        // Disable blending
        GLES20.glDisable(GLES20.GL_BLEND);

        // Set the vertex attributes
        GLES20.glVertexAttribPointer(mTexCoordHandle, 2, GLES20.GL_FLOAT, false,
            0, mTexVertices);
        GLES20.glEnableVertexAttribArray(mTexCoordHandle);
        GLES20.glVertexAttribPointer(mPosCoordHandle, 2, GLES20.GL_FLOAT, false,
            0, mPosVertices);
        GLES20.glEnableVertexAttribArray(mPosCoordHandle);
        GLToolbox.checkGlError("vertex attribute setup");

        // Set the input texture
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLToolbox.checkGlError("glActiveTexture");
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId);
        GLToolbox.checkGlError("glBindTexture");
        GLES20.glUniform1i(mTexSamplerHandle, 0);

        // Draw
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
    }

我的问题是我的猜测是否正确?并且使用FBO方法,我是否错过了一些至关重要的步骤来完成我的工作。
1个回答

0

尝试在

读取像素直接之后

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

请确保从正确的线程调用glReadPixels,即在您的渲染器子类中。
还有一件事,我看到您正在将用于FBO的纹理绑定为着色器的输入,您不能这样做。
我想,在RTT之后,您会将结果呈现到屏幕上的四边形或其他东西,对吗?
您能展示一下您正在使用的代码来读取像素的其余部分吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接