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

Flutter图片压缩报错:Instance of 'CompressError'问题求助

解决Flutter图片压缩中的CompressError问题

问题重现

使用Flutter的flutter_image_compress库实现图片压缩时,调用_compressImage()函数抛出CompressError异常,相关代码及错误日志如下:

压缩函数代码

Future<void> _compressImage() async {
  if (_image == null) {
    return;
  }

  final originalSize = _originalSize ?? await _image!.length();

  final compressedImage = await FlutterImageCompress.compressAndGetFile(
    _image!.path,
    _image!.path,
    quality: 60,
  );

  final compressedSize = await compressedImage!.length();

  setState(() {
    _image = compressedImage;
    _compressedSize = compressedSize;
  });
  print('Original Size =====> $originalSize');
  print('Compressed Size =====> $compressedSize');
}

图片选择及变量定义代码

XFile? _image;
int? _originalSize;
int? _compressedSize;
late XFile pickedImage;

Future<void> _pickImageCamera() async {
  final picker = ImagePicker();
  final pickedImage = await picker.pickImage(source: ImageSource.camera);
  if (pickedImage != null) {
    final XFile image = XFile(pickedImage.path);
    final originalSize = await image.length();
    setState(() {
      _image = image;
      _originalSize = originalSize;
      _compressedSize = null;
    });
  }
}

错误日志

E/flutter (21267): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Instance of 'CompressError'
E/flutter (21267): #0      FlutterImageCompressCommon.compressAndGetFile (package:flutter_image_compress_common/flutter_image_compress_common.dart:173:7)
E/flutter (21267): #1      FlutterImageCompress.compressAndGetFile (package:flutter_image_compress/flutter_image_compress.dart:105:22)
E/flutter (21267): #2      _ImageCompressorState._compressImage (package:ezy_img_compressor/image_compressor.dart:52:56)
E/flutter (21267): #3      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1154:21)
E/flutter (21267): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:275:24)
E/flutter (21267): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:654:11)
E/flutter (21267): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:311:5)
E/flutter (21267): #7      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:281:7)
E/flutter (21267): #8      GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:167:27)
E/flutter (21267): #9      GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:469:20)
E/flutter (21267): #10     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:445:22)
E/flutter (21267): #11     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:331:11)
E/flutter (21267): #12     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:400:7)
E/flutter (21267): #13     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:363:5)
E/flutter (21267): #14     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:320:7)
E/flutter (21267): #15     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:293:9)
E/flutter (21267): #16     _invoke1 (dart:ui/hooks.dart:158:13)
E/flutter (21267): #17     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:382:7)
E/flutter (21267): #18     _dispatchPointerDataPacket (dart:ui/hooks.dart:91:31)

错误原因分析

  • 路径冲突:compressAndGetFile函数中输入与输出路径完全相同,压缩时无法同时读取原文件并写入新文件,触发文件访问冲突。
  • 空值风险:直接使用compressedImage!强制解包,若压缩失败会导致空指针异常,加剧程序崩溃。

修复方案

修改后的压缩函数

Future<void> _compressImage() async {
  if (_image == null) {
    return;
  }

  try {
    final originalSize = _originalSize ?? await _image!.length();
    // 生成独立的输出路径,避免与原文件冲突
    final outputPath = _image!.path.replaceAll(RegExp(r'\.(jpg|jpeg|png)$'), '_compressed.$1');

    final compressedImage = await FlutterImageCompress.compressAndGetFile(
      _image!.path,
      outputPath,
      quality: 60,
    );

    if (compressedImage != null) {
      final compressedSize = await compressedImage.length();
      setState(() {
        _image = compressedImage;
        _compressedSize = compressedSize;
      });
      print('Original Size =====> $originalSize');
      print('Compressed Size =====> $compressedSize');
    } else {
      print('压缩失败:未生成压缩文件');
    }
  } catch (e) {
    print('压缩异常:$e');
  }
}

优化后的图片选择函数(可选)

XFile? _image;
int? _originalSize;
int? _compressedSize;

Future<void> _pickImageCamera() async {
  final picker = ImagePicker();
  final pickedImage = await picker.pickImage(source: ImageSource.camera);
  if (pickedImage != null) {
    final originalSize = await pickedImage.length();
    setState(() {
      _image = pickedImage;
      _originalSize = originalSize;
      _compressedSize = null;
    });
  }
}

关键优化说明

  • 独立输出路径:通过正则替换为原文件名添加_compressed后缀,确保压缩文件与原文件路径不冲突。
  • 异常捕获:用try-catch包裹压缩逻辑,捕获并打印异常信息,避免程序崩溃。
  • 空值安全:判断compressedImage不为空后再处理,消除强制解包导致的崩溃风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:12:03