You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何将CameraImage流转换为Bytes/File供Google ML Kit使用

实现方案

推荐优先使用InputImage.fromBytes构造方法,不需要额外写文件到磁盘,实时处理性能最优,也可以根据需求选择转文件的方案。

方案1:直接从Camera图像流提取Bytes构造InputImage(推荐)

CameraController返回的image是CameraImage类型,你需要先拼接图像平面的字节数据,同时构造对应的InputImageData传入即可,代码示例如下:

_cameraService.cameraController.startImageStream((image) async {
  // 1. 拼接所有图像平面的字节
  final allBytes = <int>[];
  for (var plane in image.planes) {
    allBytes.addAll(plane.bytes);
  }
  final bytes = Uint8List.fromList(allBytes);

  // 2. 构造InputImageData
  final inputImageData = InputImageData(
    size: Size(image.width.toDouble(), image.height.toDouble()),
    imageRotation: _cameraService.cameraController.description.sensorOrientation,
    inputImageFormat: InputImageFormatValue.fromRawValue(image.format.raw) ?? InputImageFormat.nv21,
    planeData: image.planes.map(
      (Plane plane) {
        return InputImagePlaneMetadata(
          bytesPerRow: plane.bytesPerRow,
          height: plane.height,
          width: plane.width,
        );
      },
    ).toList(),
  );

  // 3. 构造InputImage直接传给ML Kit
  final inputImage = InputImage.fromBytes(bytes: bytes, inputImageData: inputImageData);
  
  // 后续调用ML Kit面部检测接口即可
});

注意:如果是iOS平台,图像格式默认是bgra8888,上面的inputImageFormat自动识别逻辑可以适配,无需额外调整

方案2:转临时File使用

如果需要持久化存储图像或者更适配你的业务逻辑,可以将图像编码为图片文件存到临时目录,再用fromFile或者fromFilePath构造:

import 'dart:io';
import 'package:image/image.dart' as img;
import 'package:path_provider/path_provider.dart';

_cameraService.cameraController.startImageStream((image) async {
  // 1. 将CameraImage转换为可编码的图片格式
  img.Image convertedImage;
  if (Platform.isAndroid) {
    // Android默认是YUV420格式,转RGB
    convertedImage = img.Image.fromBytes(
      image.width,
      image.height,
      image.planes[0].bytes,
      format: img.Format.yuv420,
    );
  } else if (Platform.isIOS) {
    // iOS默认是BGRA8888格式,转RGB
    convertedImage = img.Image.fromBytes(
      image.width,
      image.height,
      image.planes[0].bytes,
      format: img.Format.bgra,
    );
  }

  // 2. 编码为png写入临时目录
  final tempDir = await getTemporaryDirectory();
  final file = File('${tempDir.path}/temp_frame.png');
  await file.writeAsBytes(img.encodePng(convertedImage));

  // 3. 构造InputImage
  final inputImage = InputImage.fromFile(file);
  // 或者 final inputImage = InputImage.fromFilePath(file.path);
});

注意:该方案因为涉及磁盘IO和图片编码,性能比方案1低,不适合高帧率实时处理场景


内容的提问来源于stack exchange,提问作者user16788731

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 10:36:03