概要: 本文主要讲解在Flutter通过Dart、JAVA和C三种方式,将相机获取的实时流数据转换为RGB格式。
目录: 1. 前言 2. Dart原生解析YUV 3. JAVA解析YUV 4. C解析YUV 5. 总结
1
前言 使用camera插件的图像流功能, 以及 如何安装camera插件这里不做过多解释。 我们主要调用camera controller 的 startImageStream 方法获取图像流。 这个方法在每次有新的帧数据时会被触发。_controller.startImageStream((CameraImage imageStream) {
//_controller.stopImageStream();
// planes include Y,U,V plane on Android
// planes include RGBA on IOS
var framesY = imageStream.planes[0].bytes;
var framesU = imageStream.planes[1].bytes;
var framesV = imageStream.planes[2].bytes;
var lenU = framesU.length;
var lenV = framesV.length;
var lenY = framesY.length;
print('$lenU'+' '+'$lenV'+' '+'$lenY');
});
输出的imageStream中包含图像的四个属性,分别是:
格式、宽度、高度和planes,其中planes中包含了图像的具体信息,下图是CameraImage的源码,请自行对照
注意:
由于FLutter是跨平台技术,所以在不同平台上获取的数据流格式也并不相同,这里只讲在Android和IOS中的格式: Android:android.graphics.ImageFormat.YUV_420_888(简称:YUV) IOS:kCVPixelFormatType_32BGRA(简称:BGRA) 由于图像格式不同,所以包含的信息也不同: Android:planes 含有三个字节数组,分别是 Y、U 和 V plane IOS:planes 只包含一个字节数组,即图像的 RGBA 字节 所以,获取到图像的planes数据只是第一步,下面的才是硬货。 解析planes数据 这里提供三种方式解析数据流,分别是Dart原生、JAVA和C,只讲Android平台的具体实例。
2
Dart解析YUV420到RGB 由于Flutter中image插件在Android和IOS上解析速度很慢,所以这种方式不建议采用,具体代码如下:import 'package:image/image.dart' as imglib;
import 'package:camera/camera.dart';
/// Flutter Camera YUV_420_888 on Android, 32RGBA on IOS
/// YUV420 to RGB converter function but is slow
Future> convertImageToPng(CameraImage image) async {
try {
imglib.Image img;
if (image.format.group == ImageFormatGroup.yuv420) {
img = _convertYUV420(image);
} else if (image.format.group == ImageFormatGroup.bgra8888) {
img = _convertBGRA8888(image);
}
imglib.PngEncoder pngEncoder = new imglib.PngEncoder();
// Convert to png
List png = pngEncoder.encodeImage(img);
return png;
} catch (e) {
print(">>>>>>>>>>>> ERROR:" + e.toString());
}
return null;
}
// CameraImage BGRA8888 -> PNG
// Color
imglib.Image _convertBGRA8888(CameraImage image) {
return imglib.Image.fromBytes(
image.width,
image.height,
image.planes[0].bytes,
format: imglib.Format.bgra,
);
}
// CameraImage YUV420_888 -> PNG -> Image (compresion:0, filter: none)
// Black
imglib.Image _conver