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



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

我做的第一个测试:

  1. 我使用GLSurfaceView显示已由android.media.effect API编辑的照片
  2. 我在包含GLSurfaceView的同一布局中添加了一个按钮
  3. 当点击按钮时,我调用glReadPixels(…)来获取照片数据。但作为第三步,我只得到了botton的数据
我想当我点击按钮时,窗口的帧缓冲区已经被按钮的内容所取代。

我做的第二个测试:

  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的方法,我是否失去了完成工作的关键一步。

尝试在之后立即读取像素

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

还要确保从正确的线程调用glReadPixels,即在渲染器子类中。

还有一件事,我看到你正在将FBO使用的纹理作为输入绑定到着色器,你不能这样做。

我想在RTT之后,你将结果渲染到屏幕上的四边形或其他东西上,对吗?

你能显示你用来读取像素的其余代码吗?

最新更新