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

如何使用ARCore捕获Android设备的相机画面(视频/静态图片)

Hey there! 作为ARCore新手,要捕获相机画面并做后续处理其实没你想的那么复杂,我来给你梳理下核心API和具体的实现示例,不管是单帧静态图还是连续视频都能搞定~

核心ARCore API选择

你主要需要用到这几个核心类的API:

  • Frame类:ARCore的帧数据容器,每帧画面的核心信息都在这里,用来获取相机原始图像
  • CameraImage类:封装了YUV格式的原始相机像素数据,支持直接处理或转成Bitmap
  • Config类:用来配置ARCore会话,比如添加自定义Surface实现视频录制
  • Session类:管理ARCore的整个会话流程,关联相机输出目标

静态图片捕获(单帧画面)

如果只需要捕获单帧静态图,用Frame.acquireCameraImage()就能获取原始相机图像,之后可以转成Bitmap或者直接处理YUV像素数据。下面是Kotlin的实现示例:

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Rect
import android.graphics.YuvImage
import android.media.ImageFormat
import android.util.Log
import com.google.ar.core.CameraImage
import com.google.ar.core.CameraImageNotAvailableException
import com.google.ar.core.Frame

// 在ARCore的帧更新回调中捕获画面
override fun onUpdateFrame(frame: Frame) {
    // 检查当前帧是否可用相机图像
    if (frame.hasDisplayGeometry() && frame.cameraImageAvailable) {
        try {
            // 使用use{}块自动释放CameraImage资源,避免内存泄漏
            frame.acquireCameraImage().use { cameraImage ->
                // 将YUV格式的相机图像转成Bitmap
                val capturedBitmap = convertYuvToBitmap(cameraImage)
                // 这里写你自己的画面处理逻辑,比如滤镜、特征识别等
                processCapturedImage(capturedBitmap)
            }
        } catch (e: CameraImageNotAvailableException) {
            Log.e("ARCoreCapture", "Failed to get camera image", e)
        }
    }
}

// 辅助方法:将CameraImage的YUV数据转成Bitmap
private fun convertYuvToBitmap(cameraImage: CameraImage): Bitmap {
    val yPlane = cameraImage.planes[0]
    val yuvImage = YuvImage(
        yPlane.buffer,
        ImageFormat.NV21,
        cameraImage.width,
        cameraImage.height,
        null
    )
    val outputStream = ByteArrayOutputStream()
    yuvImage.compressToJpeg(Rect(0, 0, cameraImage.width, cameraImage.height), 90, outputStream)
    val imageBytes = outputStream.toByteArray()
    return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
}

// 自定义的画面处理方法示例
private fun processCapturedImage(bitmap: Bitmap) {
    // 比如:给图片加个灰度滤镜,或者提取特征点
    // ... 你的处理逻辑 ...
}

注意点:

  • acquireCameraImage()必须及时释放,用use{}块是最安全的方式
  • 如果追求性能,建议直接处理YUV格式的原始数据,不用转成Bitmap(避免额外的内存开销)

视频捕获(连续画面)

ARCore本身没有内置视频录制功能,但可以结合Android的MediaRecorder来实现,通过给ARCore配置自定义Surface,让相机帧直接输出到MediaRecorder的输入源,效率很高。示例代码如下:

import android.media.MediaRecorder
import android.os.Environment
import com.google.ar.core.Config
import com.google.ar.core.Session
import java.io.File
import java.io.IOException

private lateinit var mediaRecorder: MediaRecorder
private var isRecording = false

// 初始化MediaRecorder配置
private fun initVideoRecorder() {
    mediaRecorder = MediaRecorder().apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setVideoSource(MediaRecorder.VideoSource.SURFACE)
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        // 设置视频保存路径(这里示例存在外部存储)
        setOutputFile(getVideoOutputPath())
        setVideoEncodingBitRate(10 * 1024 * 1024) // 10Mbps码率
        setVideoFrameRate(30) // 30帧每秒
        setVideoSize(1920, 1080) // 1080P分辨率
        setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        try {
            prepare()
        } catch (e: IOException) {
            Log.e("ARCoreVideo", "Failed to init MediaRecorder", e)
        }
    }
}

// 配置ARCore会话,关联MediaRecorder的Surface
private fun setupARSession(session: Session) {
    val config = Config(session)
    // 获取MediaRecorder的Surface,让ARCore把相机帧输出到这里
    val recorderSurface = mediaRecorder.surface
    config.addCameraTextureTarget(recorderSurface)
    session.configure(config)
}

// 开始录制
fun startRecording() {
    if (!isRecording) {
        mediaRecorder.start()
        isRecording = true
    }
}

// 停止录制
fun stopRecording() {
    if (isRecording) {
        try {
            mediaRecorder.stop()
        } catch (e: IllegalStateException) {
            Log.e("ARCoreVideo", "Stop recording failed", e)
        } finally {
            mediaRecorder.reset()
            isRecording = false
        }
    }
}

// 生成视频保存路径
private fun getVideoOutputPath(): String {
    val videoDir = File(
        Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
        "ARCoreCaptures"
    )
    if (!videoDir.exists()) videoDir.mkdirs()
    return "${videoDir.absolutePath}/AR_${System.currentTimeMillis()}.mp4"
}

注意点:

  • 需要申请CAMERA、RECORD_AUDIO、WRITE_EXTERNAL_STORAGE权限(Android 13+权限规则有变化,记得适配)
  • 如果需要在视频中叠加AR元素(比如虚拟物体),可以用OpenGL的帧缓冲(FBO)先渲染AR内容,再把结果输出到MediaRecorder的Surface

额外提示
  • 性能优化:画面处理逻辑尽量放在后台线程执行,避免阻塞UI线程导致AR画面卡顿
  • 内部应用用途:ARCore的API对内部使用没有特殊限制,只要遵守Google的ARCore服务条款即可
  • 调试建议:可以先从静态图片捕获开始调试,确认画面能正常获取和处理后,再扩展到视频录制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:23:57