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

Flutter中如何将MLKit的InputImage转换为Image组件?

InputImage转Flutter Image组件的解码异常解决方法

问题描述

google_mlkit_commons定义了InputImage,我用camerawesome获取相机图像并通过MLKit文本识别器分析,文本识别功能正常,但尝试用InputImage.bytes创建Image组件时抛出异常:

Failed to decode image. E/FlutterJNI(31225): android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.

问题原因

InputImage的字节数据是YUV格式(如NV21),而Flutter的Image.memory仅支持解码PNG、JPEG、RGBA等常见图像格式,无法直接解析YUV格式的原始字节流,因此导致解码失败。

解决方案

方案一:通过image库转换YUV格式为RGBA

  1. 在pubspec.yaml中添加依赖:
dependencies:
  image: ^4.0.17 # 版本可根据最新情况调整
  1. 修改_processImage方法,将NV21格式字节转换为RGBA格式后生成Image组件:
import 'package:image/image.dart' as img;

Future<void> _processImage(AnalysisImage image) async {
  final InputImage inputImage = image.toInputImage();
  if (_isBusy) return;
  _isBusy = true;
  final RecognizedText recognizedText =
      await _textRecognizer.processImage(inputImage);
  final String text = recognizedText.text.toLowerCase();
  if ((text.isNotEmpty) && (text.contains('hoje'))) {
    img.Image? convertedImage;
    if (inputImage.format == InputImageFormat.nv21) {
      final size = inputImage.size;
      // 解码NV21格式为Image对象
      convertedImage = img.decodeNv21(
        inputImage.bytes!,
        size.width.toInt(),
        size.height.toInt(),
      );
      // 根据相机旋转角度调整图像方向
      convertedImage = img.copyRotate(convertedImage, inputImage.rotation.rawValue * 90);
      // 编码为PNG字节流
      final pngBytes = img.encodePng(convertedImage);
      setState(() {
        _image = Image.memory(pngBytes);
      });
    }
  }
  _isBusy = false;
}

方案二:直接从camerawesome获取JPEG格式图像

如果不需要用YUV格式进行ML分析,可调整camerawesome配置,直接获取JPEG格式图像数据,无需额外转换即可用Image.memory显示:

// 修改CameraAwesomeBuilder的图像分析配置
CameraAwesomeBuilder.previewOnly(
  imageAnalysisConfig: AnalysisConfig(
    androidOptions: const AndroidAnalysisOptions.jpeg( // 切换为JPEG格式
      width: 1024,
    ),
    maxFramesPerSecond: 5,
    autoStart: true,
  ),
  onImageForAnalysis: _processImage,
  builder: (CameraState cameraModeState, previewSize, previewRect) {
    return AwesomeCameraLayout(state: cameraModeState);
  },
)

对应修改_processImage方法:

Future<void> _processImage(AnalysisImage image) async {
  final InputImage inputImage = image.toInputImage();
  if (_isBusy) return;
  _isBusy = true;
  final RecognizedText recognizedText =
      await _textRecognizer.processImage(inputImage);
  final String text = recognizedText.text.toLowerCase();
  if ((text.isNotEmpty) && (text.contains('hoje'))) {
    setState(() {
      // 直接使用JPEG字节创建Image组件
      _image = Image.memory(image.when(
        jpeg: (img) => img.bytes,
        nv21: (img) => img.bytes,
        bgra8888: (img) => img.bytes,
      )!);
    });
  }
  _isBusy = false;
}

注意事项

  • 方案一中要注意匹配相机的旋转角度,避免图像显示方向错误;
  • 方案二中MLKit文本识别器同样支持JPEG格式的InputImage,不会影响原有识别功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 14:45:10