Flutter:在不使用文件的情况下将 Image 对象转换为 base64 字符串
Flutter: converting an Image object to a base64 string without using a File
我在某处抓取了以下代码,无需访问文件即可将图片转换为 base64 字符串:
String ImageToString(Image image) {
String result;
var stream = image.image.resolve(const ImageConfiguration());
stream.addListener(ImageStreamListener((imageInfo, _) async {
var byteData =
await imageInfo.image.toByteData(format: ImageByteFormat.png);
var data = byteData!.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
result = base64Encode(data);
}));
// Need to wait for completion here
return result;
}
问题是我需要等待异步任务完成。
- 这种情况下如何等待完成?
- 否则,是否有同步等待来执行此操作?
我花了整整两天的时间研究这个问题并阅读了很多资料:
- 根据 Dart 开发人员的以下长篇 discussion,Dart 的
waitFor
现在已被弃用,并且很可能有一天会消失。
- 此外,
waitFor
由于某些不兼容问题一直无法在 Flutter 中使用,因为 Dart 已经在内部针对 Flutter 的需求进行了深度适配。
- 它在 Dart 中的弃用意味着它不会在 Flutter 中引入。
所以这里是Dart/Flutter中如何处理这个:
- 只有一个
async
函数可以 await
另一个 async
函数。
- 所有
async
函数必须 return 一个 Future<...>
(即使是 Future<void>
),因此强制其调用者也是 async
,并且等等。
- 切断这些
async
函数调用链的唯一方法是到达 main
函数或能够允许在某个点(例如小部件的例如构建方法)。
- 还有另一种减少这些
async
链的方法。例如,假设您在程序的某个位置需要 /tmp 目录的路径。这是一个 sync
操作。现在,由于此路径不会更改,您可以在应用程序初始化时设置一个全局变量。这个一般是直接在main
,或者是它调用的一个函数
最后但同样重要的是:
- 对于任何异步例程,您必须特别注意在参数中传递所有需要的信息以保持数据完整性,因为
async
函数的执行会延迟,并且在 async
例程有机会执行之前,这些数据可能会在您的应用程序中更改。 Inbound 副作用因此永远不应成为此处的选项。
- 请牢记 在这方面,您应该始终将对象的副本传递给
async
例程!!事实上,在Dart/Flutter中,只有对象的引用是按值传递的,而不是对象本身!!这意味着修改对象可能会产生副作用,无论是入站还是出站,都可能导致数据损坏,例如,在将数据保存在文件中时。
希望对您有所帮助。
我在某处抓取了以下代码,无需访问文件即可将图片转换为 base64 字符串:
String ImageToString(Image image) {
String result;
var stream = image.image.resolve(const ImageConfiguration());
stream.addListener(ImageStreamListener((imageInfo, _) async {
var byteData =
await imageInfo.image.toByteData(format: ImageByteFormat.png);
var data = byteData!.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
result = base64Encode(data);
}));
// Need to wait for completion here
return result;
}
问题是我需要等待异步任务完成。
- 这种情况下如何等待完成?
- 否则,是否有同步等待来执行此操作?
我花了整整两天的时间研究这个问题并阅读了很多资料:
- 根据 Dart 开发人员的以下长篇 discussion,Dart 的
waitFor
现在已被弃用,并且很可能有一天会消失。 - 此外,
waitFor
由于某些不兼容问题一直无法在 Flutter 中使用,因为 Dart 已经在内部针对 Flutter 的需求进行了深度适配。 - 它在 Dart 中的弃用意味着它不会在 Flutter 中引入。
所以这里是Dart/Flutter中如何处理这个:
- 只有一个
async
函数可以await
另一个async
函数。 - 所有
async
函数必须 return 一个Future<...>
(即使是Future<void>
),因此强制其调用者也是async
,并且等等。 - 切断这些
async
函数调用链的唯一方法是到达main
函数或能够允许在某个点(例如小部件的例如构建方法)。 - 还有另一种减少这些
async
链的方法。例如,假设您在程序的某个位置需要 /tmp 目录的路径。这是一个sync
操作。现在,由于此路径不会更改,您可以在应用程序初始化时设置一个全局变量。这个一般是直接在main
,或者是它调用的一个函数
最后但同样重要的是:
- 对于任何异步例程,您必须特别注意在参数中传递所有需要的信息以保持数据完整性,因为
async
函数的执行会延迟,并且在async
例程有机会执行之前,这些数据可能会在您的应用程序中更改。 Inbound 副作用因此永远不应成为此处的选项。 - 请牢记 在这方面,您应该始终将对象的副本传递给
async
例程!!事实上,在Dart/Flutter中,只有对象的引用是按值传递的,而不是对象本身!!这意味着修改对象可能会产生副作用,无论是入站还是出站,都可能导致数据损坏,例如,在将数据保存在文件中时。
希望对您有所帮助。