You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Flutter camera插件拍摄的图片如何正确压缩减小体积?

你代码出现无响应的核心原因有两个:

  • 你用的readAsBytesSync、writeAsBytesSync都是同步IO操作,加上图片解码编码本身是计算密集型任务,直接在UI主线程执行会阻塞线程,导致应用无响应
  • 你调用了resizeImage方法但没有接收它的返回值,还是把原未压缩的文件赋值给了imageFile,压缩逻辑就算跑成功也不会生效

修正后的代码

首先把压缩方法改为异步实现,避免阻塞主线程:

Future<XFile> resizeImage(XFile img) async {
  // 用异步方法读取文件
  final imageBytes = await File(img.path).readAsBytes();
  final image = imageP.decodeJpg(imageBytes);
  final thumbnail = imageP.copyResize(image, width: 400);
  // 可调整quality参数(0-100)控制压缩质量,数值越小压缩率越高
  final compressedBytes = imageP.encodeJpg(thumbnail, quality: 85);
  // 异步写入压缩后的图片数据
  await File(img.path).writeAsBytes(compressedBytes);
  return XFile(img.path);
}

再调整拍照按钮的点击逻辑,等待压缩完成再更新状态:

void onTakePictureButtonPressed() {
  takePicture().then((XFile? file) async {
    if (mounted && file != null) {
      // 等待压缩逻辑执行完成
      final compressedFile = await resizeImage(file);
      setState(() {
        imageFile = compressedFile;
        videoController?.dispose();
        videoController = null;
      });
      showInSnackBar('图片已保存到 ${compressedFile.path}');
    }
  });
}

可选优化方案

如果图片分辨率很高,压缩逻辑还是有卡顿的话,可以把图片处理逻辑放到Isolate中执行,完全不占用主线程资源:

// 注意这个方法要放在类外部作为顶级函数
imageP.Image resizeIsolate(Uint8List bytes) {
  return imageP.copyResize(imageP.decodeJpg(bytes)!, width: 400);
}

// 调整后的压缩方法
Future<XFile> resizeImage(XFile img) async {
  final imageBytes = await File(img.path).readAsBytes();
  // 把解码缩放逻辑放到独立线程执行
  final thumbnail = await compute(resizeIsolate, imageBytes);
  final compressedBytes = imageP.encodeJpg(thumbnail, quality: 85);
  await File(img.path).writeAsBytes(compressedBytes);
  return XFile(img.path);
}

内容的提问来源于stack exchange,提问作者ramya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 06:27:03