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

如何在Agora Flutter中将VideoFrame转换为JPEG格式?

解决方案:将Agora VideoFrame的YUV数据转换为JPEG

要实现从YUV缓冲区生成JPEG,核心是先将YUV420格式的像素数据转换为RGB,再编码为JPEG。以下是具体步骤和代码:

1. 添加依赖

在pubspec.yaml中引入image库用于图像处理:

dependencies:
  image: ^4.0.17

2. 完整转换代码

在onCaptureVideoFrame回调中实现转换逻辑:

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

onCaptureVideoFrame: (VideoSourceType sourceType, VideoFrame videoFrame) async {
  Uint8List yData = videoFrame.yBuffer!;
  Uint8List uData = videoFrame.uBuffer!;
  Uint8List vData = videoFrame.vBuffer!;
  int height = videoFrame.height!;
  int width = videoFrame.width!;

  // 创建RGB格式的图像对象
  final rgbImage = img.Image(width, height);
  final uvWidth = width ~/ 2;
  final uvHeight = height ~/ 2;

  // YUV420P转RGB(BT.601标准)
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      final yVal = yData[y * width + x] & 0xff;
      final uvX = x ~/ 2;
      final uvY = y ~/ 2;
      final uVal = uData[uvY * uvWidth + uvX] & 0xff;
      final vVal = vData[uvY * uvWidth + uvX] & 0xff;

      // 计算RGB值
      int r = (yVal + 1.370705 * (vVal - 128)).round();
      int g = (yVal - 0.698001 * (vVal - 128) - 0.337633 * (uVal - 128)).round();
      int b = (yVal + 1.732446 * (uVal - 128)).round();

      // 限制值在0-255范围内
      r = r.clamp(0, 255);
      g = g.clamp(0, 255);
      b = b.clamp(0, 255);

      rgbImage.setPixelRgb(x, y, r, g, b);
    }
  }

  // 编码为JPEG字节数据
  final Uint8List jpegBytes = img.encodeJpg(rgbImage, quality: 80);

  // jpegBytes即可用于TFLite模型输入或其他操作
},

注意事项

  • 性能优化:逐像素遍历在高分辨率下可能存在性能瓶颈,若需要更高效的转换,可考虑使用原生扩展或直接操作Uint32List批量处理像素。
  • 格式确认:确保Agora返回的是YUV420P(I420)格式,可通过videoFrame.format判断(如VideoFormat.yuv420),若为其他YUV格式(如NV21),需调整UV分量的读取逻辑。
  • 模型适配:如果你的TFLite模型支持直接处理YUV数据,建议跳过RGB转换步骤,直接使用YUV缓冲区输入,能大幅提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:56:22