在今天编写vision类的时候,遇到这么一个问题,我们需要从Image
Widget中获取到图像的二进制数据。观察过源码之后发现,Image
是对ImageProvider
中的数据流进行了注册监听,用到了回调。我们采用同样的方式去获取ImageInfo
对象,虽然ImagePrivider
对我们提供了ImageStream
,但是ImageStream
类并不是继承自Stream
,所以对于Stream
提供的那些方法自然不能奏效。只能采取ImageStream
提供的方案:ImageStreamListener
,但是这样一来我们就只能通过ImageStreamListener
参数中的回调函数来处理返回的数据,这样既不利于我们思维理解,也不利于数据的处理,那么有没有一种办法是可以将这种回调方式转化为Future返回值呢?答案当然是存在这种办法的。
解决方法如下:
final Completer<ByteData> completer = Completer();
ImageStreamListener listener;
listener = ImageStreamListener((ImageInfo image, bool synchronousCall) {
completer.complete(image.image.toByteData());
newStream.removeListener(listener);
});
newStream.addListener(listener);
final bytes = (await completer.future).buffer.asUint8List();
final visionImage = FirebaseVisionImage.fromBytes(
bytes,
FirebaseVisionImageMetadata(
size: Size(widget.width, widget.height),
rawFormat: null,
planeData: null,
));
其中Dartlang中的Completer
对象就可以将这种回调传值的方式转化为Future返回值,仔细想一下,是不是和Java中的CountDownLatch
可以起到的作用是不是很类似呢。