prepareCameraFrameFromImage function
- Object cameraImage, {
- CameraFrameRotation? rotation,
- bool? isBgra,
Convenience wrapper around prepareCameraFrame that accepts any object
duck-typed to package:camera's CameraImage (i.e. exposing width,
height, and a planes iterable of objects with bytes, bytesPerRow,
and bytesPerPixel getters).
This keeps flutter_litert free of a hard dependency on package:camera
while letting callers pass a CameraImage directly:
camera.startImageStream((CameraImage image) async {
final frame = prepareCameraFrameFromImage(image);
if (frame == null) return;
final faces = await detector.detectFacesFromCameraFrame(frame);
});
Throws at runtime (NoSuchMethodError / TypeError) if cameraImage does
not expose the expected shape; this is an acceptable tradeoff vs. either
adding a camera dep here or asking every caller to write a plane mapper.
When isBgra is null, a desktop single-plane frame's byte order comes from
the image's format.raw: 'BGRA' selects BGRA and 'RGBA' selects RGBA.
camera_desktop 2.x reports 'BGRA' on every desktop platform, while 1.x
reported 'RGBA' on Linux and Windows. Any other value, including a missing
format or a non-string raw, falls back to BGRA on macOS and RGBA
elsewhere. An explicit isBgra always wins.
See prepareCameraFrame for parameter semantics.
Implementation
CameraFrame? prepareCameraFrameFromImage(
Object cameraImage, {
CameraFrameRotation? rotation,
bool? isBgra,
}) {
// ignore: avoid_dynamic_calls
final dynamic dyn = cameraImage;
final int width = dyn.width as int;
final int height = dyn.height as int;
final Iterable<dynamic> rawPlanes = dyn.planes as Iterable<dynamic>;
final planes = <CameraPlane>[
for (final dynamic p in rawPlanes)
(
bytes: p.bytes as Uint8List,
rowStride: p.bytesPerRow as int,
pixelStride: (p.bytesPerPixel as int?) ?? 1,
),
];
return prepareCameraFrame(
width: width,
height: height,
planes: planes,
rotation: rotation,
isBgra: isBgra ?? _defaultIsBgra(dyn),
);
}