压缩图像时 UI 冻结

dda*_*ang 1 flutter flutter-layout

我正在尝试压缩来自相机或图库的图像,但我尝试在这个问题Flutter & Firebase: Compression before upload image中回答

但是 UI 被冻结了,请问你们有什么解决方案吗?为什么图像插件会遇到这个问题?

更新:

compressImage(imageFile).then((File file) {
   imageFile = file;
});

Future<File> compressImage(File imageFile) async {
   return compute(decodeImage, imageFile);
}

File decodeImage(File imageFile) {
   Im.Image image = Im.decodeImage(imageFile.readAsBytesSync());
   Im.Image smallerImage = Im.copyResize(
       image, 150); // choose the size here, it will maintain aspect ratio
   return new File('123.jpg')
     ..writeAsBytesSync(Im.encodeJpg(smallerImage, quality: 85));
}
Run Code Online (Sandbox Code Playgroud)

我在此代码中遇到“未处理的异常”

Gün*_*uer 5

这是因为压缩是在 UI 线程中完成的。

您可以使用https://docs.flutter.io/flutter/foundation/compute.html将计算移动到新线程compute()

当前非 UI 线程可以执行的操作存在严重限制。

  • 如果传递图像数据,则会将其从一个线程复制到另一个线程,这可能会很慢。如果您将图像放在文件中,就像从中获取图像一样image_picker,最好传递文件路径并在新线程中读取图像。

  • 您只能传递可以编码为 JSON 的值(它实际上并未编码为 JSON,但它支持相同的类型)

  • 您不能使用插件。这意味着您需要通过传递数据(再次复制)或通过写入文件并传回文件路径来将压缩数据移回 UI 线程,但在这种情况下,复制可能会更快,因为写入在一个线程中读取文件并在另一个线程中读取它甚至更慢)。然后,您可以在 UI 线程中调用将图像上传到 Firebase Cloud Storage,但由于这是一个插件,它将在本机代码中运行,而不是在 UI 线程中运行。只是 UI 线程需要传递图像。