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
相关产品推荐
相关产品推荐

