Flutter中startImageStream返回CameraImage的planes.height为null的问题
解决CameraImage中Plane height为null的问题
问题根源
在camera:^0.10.0版本中,部分设备或特定分辨率预设下,startImageStream返回的CameraImage对象的Plane属性(height/width)可能为null。这是因为底层相机框架未直接传递这些值,或返回的图像格式与预期结构不符。
解决方案
1. 规范相机初始化与流启动逻辑
不要用setState包裹startImageStream调用,相机完全初始化后直接启动流即可,避免UI重建导致的状态混乱,同时指定标准图像格式保证Plane结构稳定:
initCamera() async { try { cameraController = CameraController( cameras[0], ResolutionPreset.medium, imageFormatGroup: ImageFormatGroup.yuv420, // 强制使用YUV420格式,确保Plane结构可预测 ); await cameraController.initialize(); if (!mounted) return; cameraController.startImageStream((imageFromStream) async { if (!isWorking) { isWorking = true; await preprocessImage(imageFromStream); isWorking = false; // 处理完成后重置状态,保证后续帧能被处理 } }); setState(() {}); // 仅在需要更新UI时调用 } catch(e) { print(e); } }
2. 从相机预览尺寸获取Plane真实尺寸
如果imageFromStream.planes[0].height为null,直接从cameraController.value.previewSize获取宽高——因为相机初始化完成后,预览尺寸是确定存在的:
preprocessImage(CameraImage cameraImage) async { final previewSize = cameraController.value.previewSize; if (previewSize == null) { print("预览尺寸未初始化"); isWorking = false; return null; } final planes = cameraImage.planes; final yPlane = planes[0]; final uvPlane = planes[1]; // Y平面尺寸对应完整预览尺寸 final yHeight = previewSize.height; final ySize = yPlane.bytesPerRow * yHeight; // UV平面尺寸为预览尺寸的一半(YUV420格式特性) final uvHeight = previewSize.height ~/ 2; final uvSize = uvPlane.bytesPerRow * uvHeight; final bytes = Uint8List(ySize + uvSize); // 填充Y平面 bytes.setRange(0, ySize, yPlane.bytes); // 填充UV平面 final uvOffset = ySize; for (var i = 0; i < uvHeight; i++) { final srcOffset = i * uvPlane.bytesPerRow; final destOffset = uvOffset + i * (previewSize.width ~/ 2) * 2; bytes.setRange(destOffset, destOffset + uvPlane.bytesPerRow, uvPlane.bytes, srcOffset); } return bytes; }
3. 优化状态管理与异常兜底
- 确保
isWorking在图像处理完成后(无论成功或失败)重置,避免只处理一帧就停止后续流。 - 在
preprocessImage开头添加预览尺寸的null检查,避免意外崩溃。
关键说明
指定imageFormatGroup: ImageFormatGroup.yuv420是核心优化点,它强制相机返回标准YUV420格式,让Plane的结构完全可预测,从根源上减少因设备默认格式差异导致的属性缺失问题。
内容的提问来源于stack exchange,提问作者Parikshit23
相关产品推荐
相关产品推荐

