buildAndroidInputImage static method

InputImage? buildAndroidInputImage(
  1. CameraImage image,
  2. InputImageRotation rotation
)

Implementation

static InputImage? buildAndroidInputImage(CameraImage image, InputImageRotation rotation) {
  final int width = image.width;
  final int height = image.height;

  if (image.planes.length == 1) {
    final bytes = image.planes[0].bytes;

    return InputImage.fromBytes(
      bytes: bytes,
      metadata: InputImageMetadata(
        size: Size(width.toDouble(), height.toDouble()),
        rotation: rotation,
        format: InputImageFormat.nv21,
        bytesPerRow: image.planes[0].bytesPerRow,
      ),
    );
  }

  // For old flutter version
  if (image.planes.length < 3) {
    print("Unexpected number of planes: ${image.planes.length}");
    return null;
  }

  final yPlane = image.planes[0];
  final uPlane = image.planes[1];
  final vPlane = image.planes[2];

  final yRowStride = yPlane.bytesPerRow;
  final uvRowStride = uPlane.bytesPerRow;
  final uvPixelStride = uPlane.bytesPerPixel ?? 2;

  final WriteBuffer buffer = WriteBuffer();

  for (int row = 0; row < height; row++) {
    final int offset = row * yRowStride;
    final int end = offset + width;
    if (end <= yPlane.bytes.length) {
      buffer.putUint8List(yPlane.bytes.sublist(offset, end));
    }
  }

  for (int row = 0; row < height ~/ 2; row++) {
    for (int col = 0; col < width ~/ 2; col++) {
      final int offset = row * uvRowStride + col * uvPixelStride;
      if (offset < vPlane.bytes.length && offset < uPlane.bytes.length) {
        buffer.putUint8(vPlane.bytes[offset]);
        buffer.putUint8(uPlane.bytes[offset]);
      }
    }
  }

  final bytes = buffer.done().buffer.asUint8List();

  return InputImage.fromBytes(
    bytes: bytes,
    metadata: InputImageMetadata(
      size: Size(width.toDouble(), height.toDouble()),
      rotation: rotation,
      format: InputImageFormat.nv21,
      bytesPerRow: width,
    ),
  );
}