在Android中,可以使用SurfaceTexture类来保存先前的纹理以供以后使用。下面是一个简单的示例代码,展示了如何使用SurfaceTexture来保存纹理:
public class MySurfaceTextureActivity extends Activity implements SurfaceTexture.OnFrameAvailableListener {
private Camera mCamera;
private SurfaceTexture mSurfaceTexture;
private int mTextureId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建一个新的SurfaceTexture对象
mSurfaceTexture = new SurfaceTexture(0);
// 设置OnFrameAvailableListener,当有新纹理可用时会回调该方法
mSurfaceTexture.setOnFrameAvailableListener(this);
// 获取一个新的纹理id
int[] textures = new int[1];
GLES20.glGenTextures(1, textures, 0);
mTextureId = textures[0];
// 绑定纹理对象
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureId);
// 将SurfaceTexture与纹理对象进行关联
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
// 将纹理与SurfaceTexture进行关联
mSurfaceTexture.attachToGLContext(mTextureId);
// 打开相机
mCamera = Camera.open();
try {
// 设置相机预览纹理
mCamera.setPreviewTexture(mSurfaceTexture);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFrameAvailable(SurfaceTexture surfaceTexture) {
// 当有新纹理可用时,可以保存纹理供以后使用
// 在这里可以将纹理保存到文件或者内存中
// 例如可以使用OpenGL ES的glReadPixels方法将纹理保存为Bitmap
// Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
// GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, bmp);
// 在保存完纹理后,需要调用updateTexImage方法来通知SurfaceTexture可以继续接收新的纹理数据
surfaceTexture.updateTexImage();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 释放相机资源
mCamera.stopPreview();
mCamera.release();
// 删除纹理对象
int[] textures = new int[]{mTextureId};
GLES20.glDeleteTextures(1, textures, 0);
}
}
在这个示例中,我们首先创建一个SurfaceTexture对象,并设置OnFrameAvailableListener,当有新纹理可用时会回调onFrameAvailable方法。然后创建一个新的纹理对象,并将纹理与SurfaceTexture进行关联。接下来,我们打开相机,并将相机预览纹理设置为SurfaceTexture。当有新纹理可用时,onFrameAvailable方法会被回调。在这个方法中,你可以将纹理保存到文件或者内存中,然后调用updateTexImage方法通知SurfaceTexture可以继续接收新的纹理数据。最后,在Activity的onDestroy方法中,我们释放相机资源并删除纹理对象。
需要注意的是,在保存纹理时,你可以使用OpenGL ES的glReadPixels方法将纹理保存为Bitmap,或者使用其他方法将纹理保存为文件。