如何捕获带虚拟对象的ARCore屏幕内容(非重复问题)
ARCore 1.27.0+ 捕获GLSurfaceView内容解决方案
针对SceneForm弃用后原PixelCopy方案失效的场景,可直接通过GLSurfaceView自带的GL上下文读取帧缓存实现内容捕获,具体实现步骤如下:
核心实现步骤
- 第一步:先调整GLSurfaceView的渲染模式,避免捕获过程中画面刷新导致内容错乱
// 捕获前先切换为手动渲染模式 glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); glSurfaceView.requestRender(); - 第二步:在GLSurfaceView.Renderer的
onDrawFrame回调中执行帧读取逻辑,只有这个阶段GL上下文处于活跃状态,可以正常读取帧缓存@Override public void onDrawFrame(GL10 gl) { // 先执行原有渲染逻辑:AR背景绘制、自定义3D对象绘制 // ... 原有渲染代码保持不变 // 渲染完成后执行捕获逻辑 if (isCaptureRequested) { int width = glSurfaceView.getWidth(); int height = glSurfaceView.getHeight(); ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4); buffer.order(ByteOrder.LITTLE_ENDIAN); GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buffer); // 转换为Bitmap并处理坐标翻转(GL原点在左下角,Bitmap原点在左上角) Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); bitmap.copyPixelsFromBuffer(buffer); Matrix matrix = new Matrix(); matrix.postScale(1, -1); Bitmap flippedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, false); bitmap.recycle(); // 此处可处理生成的flippedBitmap,比如保存到本地、回传给UI线程展示 // ... 自定义业务逻辑 // 捕获完成后重置标记,按需恢复自动渲染 isCaptureRequested = false; glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY); } }
注意事项
- 必须保证
glReadPixels执行在GL线程(也就是onDrawFrame回调中),在UI线程直接调用会因无GL上下文获取到纯黑或者空白内容 - 如果你的AR场景包含普通View叠加在GLSurfaceView之上,需要额外将View绘制到同一个Bitmap中合并,该方案仅捕获GLSurfaceView本身的渲染内容
- 若使用的是ARCore 1.27.0+推荐的Filament渲染框架替代SceneForm,也可以直接复用Filament提供的
capture方法获取渲染帧,逻辑和上述方案一致,不需要依赖PixelCopy。
内容的提问来源于stack exchange,提问作者digiwizkid
相关产品推荐
相关产品推荐

