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

Unity ARCore中调用AcquireCameraImageBytes()保存相机图像至本地存储

如何在Unity + ARCore 1.1中获取相机数据并保存为JPG到本地

我完全懂你的痛点——ARCore 1.1给Unity开发者提供了更灵活的相机数据获取API,但官方示例只停留在数据获取和基础处理,完全没讲怎么把这些数据存成本地JPG。下面我给你一套经过验证的完整方案,包含代码和关键细节:

实现步骤拆解

首先得明确整个流程的核心逻辑:

  • 从ARCore的Frame.CameraImage拿到原始YUV格式的相机帧
  • 把YUV数据转成Unity能处理的Texture2D
  • 将纹理编码为JPG字节流
  • 写入到本地存储(还要注意Android的权限问题)

完整代码实现

你可以直接把这个脚本挂在AR会话的Manager对象上,或者单独创建一个控制对象:

using UnityEngine;
using GoogleARCore;
using System.IO;

public class ARCameraCapture : MonoBehaviour
{
    private Texture2D _cameraTexture;

    // 绑定到UI按钮或者用代码调用这个方法来触发保存
    public void CaptureAndSaveCameraFrame()
    {
        // 先检查AR会话状态是否正常
        if (Session.Status != SessionStatus.Tracking)
        {
            Debug.LogWarning("AR会话未追踪,无法捕获相机帧");
            return;
        }

        using (var cameraImage = Frame.CameraImage)
        {
            if (!cameraImage.IsAvailable)
            {
                Debug.LogWarning("当前相机图像不可用");
                return;
            }

            // 初始化纹理,避免重复创建
            if (_cameraTexture == null || _cameraTexture.width != cameraImage.Width || _cameraTexture.height != cameraImage.Height)
            {
                _cameraTexture = new Texture2D(cameraImage.Width, cameraImage.Height, TextureFormat.RGBA32, false);
            }

            // 设置转换参数:把YUV转成RGBA,调整方向匹配显示
            var conversionParams = new CameraImageConversionParams(
                cameraImage,
                TextureFormat.RGBA32,
                CameraImageTransformation.Rotation0,
                CameraImageTransformation.MirrorY);

            // 执行格式转换
            cameraImage.Convert(conversionParams, _cameraTexture.GetRawTextureData<byte>(), _cameraTexture.width * _cameraTexture.height * 4);
            _cameraTexture.Apply();

            // 编码为JPG,质量设为90(0-100,越高画质越好)
            byte[] jpgData = _cameraTexture.EncodeToJPG(90);

            // 生成带时间戳的文件名,避免重复
            string fileName = $"ARCapture_{System.DateTime.Now:yyyyMMdd_HHmmss}.jpg";
            // 用persistentDataPath确保Android上有写入权限
            string savePath = Path.Combine(Application.persistentDataPath, fileName);

            // 写入文件
            File.WriteAllBytes(savePath, jpgData);

            Debug.Log($"相机帧已保存:{savePath}");
        }
    }

    private void Start()
    {
        #if UNITY_ANDROID && !UNITY_EDITOR
        // Android 6.0+需要动态申请存储权限
        AndroidPermissionsManager.RequestPermission(AndroidPermission.ExternalStorageWrite);
        #endif
    }
}

关键细节说明

  • YUV转RGBA的必要性:ARCore相机输出的是YUV_420_888格式,Unity的Texture2D无法直接处理这种格式,必须用CameraImage.Convert()转换为RGBA32才能编码为JPG
  • 权限处理:Android系统从6.0开始要求动态申请外部存储读写权限,所以在Start()方法里加了权限请求逻辑,没有权限的话文件写入会失败
  • 性能优化:重复使用同一个Texture2D,避免每次捕获都创建新纹理,减少GC开销
  • 路径选择:Application.persistentDataPath是Unity在Android上推荐的可写入路径,你也可以改成公共图片目录,但需要额外的权限配置

注意事项

  • 必须在Android真机上测试,编辑器里无法获取ARCore的相机数据
  • 如果你的AR场景需要调整相机方向,可以修改CameraImageTransformation的参数(比如Rotation90)来匹配显示效果
  • 要是担心卡顿,可以把文件写入逻辑放到异步方法里执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:20:47