prepareCameraFrame function
CameraFrame?
prepareCameraFrame({
- required int width,
- required int height,
- required List<
CameraPlane> planes, - CameraFrameRotation? rotation,
- bool isBgra = true,
Prepare a CameraFrame descriptor from raw camera planes, for use with a
detector package's detectFromCameraFrame(...) method.
Auto-detects the layout based on plane count and pixel stride:
- 1 plane,
pixelStride >= 4-> packed BGRA (or RGBA ifisBgrais false). Theplanesbuffer is referenced directly; no copy. - 2 planes -> NV12. Repacked tightly via
packYuv420. - 3 planes -> NV21 or I420 (auto-detected from U pixel stride). Repacked
tightly via
packYuv420.
Returns null for unsupported shapes (empty planes, missing U plane for YUV, odd width/height for YUV420).
isBgra selects BGRA (macOS, default) vs. RGBA (Linux) for the desktop
single-plane path; it is ignored for YUV input.
Typical usage:
camera.startImageStream((CameraImage image) async {
final frame = prepareCameraFrame(
width: image.width,
height: image.height,
planes: [
for (final p in image.planes)
(bytes: p.bytes, rowStride: p.bytesPerRow,
pixelStride: p.bytesPerPixel ?? 1),
],
);
if (frame == null) return;
final faces = await detector.detectFacesFromCameraFrame(frame);
});
Implementation
CameraFrame? prepareCameraFrame({
required int width,
required int height,
required List<CameraPlane> planes,
CameraFrameRotation? rotation,
bool isBgra = true,
}) {
if (planes.isEmpty) return null;
// Desktop single-plane 4-channel BGRA/RGBA.
if (planes.length == 1 && planes[0].pixelStride >= 4) {
final p = planes[0];
return CameraFrame(
bytes: p.bytes,
width: width,
height: height,
strideCols: p.rowStride ~/ 4,
conversion: isBgra
? CameraFrameConversion.bgra2bgr
: CameraFrameConversion.rgba2bgr,
rotation: rotation,
);
}
// YUV420 (2 planes for NV12, 3 for NV21 or I420).
if (planes.length < 2) return null;
final y = planes[0];
final u = planes[1];
final v = planes.length > 2 ? planes[2] : null;
final packed = packYuv420(width: width, height: height, y: y, u: u, v: v);
if (packed == null) return null;
return CameraFrame(
bytes: packed.bytes,
width: packed.width,
height: packed.height,
strideCols: packed.width,
conversion: switch (packed.layout) {
YuvLayout.nv12 => CameraFrameConversion.yuv2bgrNv12,
YuvLayout.nv21 => CameraFrameConversion.yuv2bgrNv21,
YuvLayout.i420 => CameraFrameConversion.yuv2bgrI420,
},
rotation: rotation,
);
}