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;
  }

问题是我需要等待异步任务完成。

  1. 这种情况下如何等待完成?
  2. 否则,是否有同步等待来执行此操作?

我花了整整两天的时间研究这个问题并阅读了很多资料:

  • 根据 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中,只有对象的引用是按值传递的,而不是对象本身!!这意味着修改对象可能会产生副作用,无论是入站还是出站,都可能导致数据损坏,例如,在将数据保存在文件中时。

希望对您有所帮助。