如何在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
相关产品推荐
相关产品推荐

