You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中CameraX连接SurfaceTexture及提升ImageAnalysis帧率问题

CameraX + OpenGL 帧获取帧率异常问题

背景

我正在开发一款基于OpenGL的Android应用,通过以下方式将CameraTexture连接到CameraX的Preview用例:

val surfaceProvider = getSurfaceProvider(res)

preview.setSurfaceProvider(surfaceProvider)

初始化surfaceProvider的代码如下:

private fun getSurfaceProvider(resolution: Size): SurfaceProvider? {
    return SurfaceProvider { request: SurfaceRequest ->
        val r = request.resolution

        cameraTexture!!.setDefaultBufferSize(r.width, r.height)
        effectTexture!!.setDefaultBufferSize(r.width, r.height)

        val surface = Surface(surfaceTexture)
        request.provideSurface(surface,
            executor
        ) {}
    }
}

我的需求是从主SurfaceTexture中每秒获取30帧Bitmap来添加特效,但尝试glReadPixels和readPixelsFromPBO两种方式时,都会导致相机流暂停,这个问题已经困扰我一个月,试过各种方案都没解决。

尝试方案:搭配ImageAnalysis用例

我尝试同时使用ImageAnalysis和Preview用例,虽然能运行但帧率极低,只有10fps(Preview本身帧率正常)。即使只执行ImageProxy转Bitmap的操作(未做任何额外繁重处理),帧率还是上不去。我已经查阅了ImageAnalysis文档和背压策略相关内容,试过所有背压选项,问题依旧存在。转Bitmap的代码如下:

imageProxy.toBitmap() 
fun ImageProxy.toBitmap(): Bitmap {
        val yBuffer = planes[0].buffer // Y
        val vuBuffer = planes[2].buffer // VU

        val ySize = yBuffer.remaining()
        val vuSize = vuBuffer.remaining()

        val nv21 = ByteArray(ySize + vuSize)

        yBuffer.get(nv21, 0, ySize)
        vuBuffer.get(nv21, ySize, vuSize)

        val yuvImage = YuvImage(nv21, ImageFormat.NV21, this.width, this.height, null)
        val out = ByteArrayOutputStream()
        yuvImage.compressToJpeg(Rect(0, 0, yuvImage.width, yuvImage.height), 50, out)
        val imageBytes = out.toByteArray()
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
    }

补充说明

我没有使用PreviewView,而是用了TextureView,所以没法像用PreviewView那样便捷地获取Bitmap。

内容的提问来源于stack exchange,提问作者Mohammad Elsayed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 07:55:16