image_util.dart 3.41 KB
import 'dart:io';

import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
import 'package:path_provider/path_provider.dart';

class ImageUtil {
  /// 使用 ffmpeg_kit_flutter_new 生成指定图片的缩略图
  ///
  /// [imagePath] 原始图片路径
  /// [width] 缩略图宽度,默认值为320
  /// [quality] JPEG 输出质量 (1-32,数值越小质量越高),默认值为18
  /// 返回缩略图路径
  static Future<String?> genTempThumbnail(String imagePath, {int width = 320, int quality = 18}) async {
    try {
      // 检查源文件是否存在
      final imageFile = File(imagePath);
      if (!await imageFile.exists()) {
        print('源图片文件不存在: $imagePath');
        return null;
      }

      // 创建临时文件路径用于存储缩略图
      final tempDir = await getTemporaryDirectory();
      final thumbnailPath = '${tempDir.path}/thumb_${DateTime.now().millisecondsSinceEpoch}.jpg';

      // 使用 FFmpeg 生成缩略图
      // 构建 FFmpeg 命令行参数
      String cmd = '-i "$imagePath" ' // 指定输入文件路径
          '-vf scale=$width:-1:flags=lanczos ' // 设置缩略图宽度,高度等比缩放,使用 Lanczos 算法提高质量
          '-q:v $quality ' // 设置 JPEG 输出质量 (1-32,数值越小质量越高)
          '-y ' // 覆盖已存在的输出文件
          // '-pix_fmt yuvj420p ' // 指定像素格式以提高兼容性
          '"$thumbnailPath"'; // 指定输出文件路径

      // 执行 FFmpeg 命令
      final session = await FFmpegKit.execute(cmd);
      final returnCode = await session.getReturnCode();

      // 检查执行结果
      if (ReturnCode.isSuccess(returnCode)) {
        return thumbnailPath;
      } else {
        print('生成图片缩略图失败: ${await session.getFailStackTrace()}');
        return null;
      }
    } catch (e) {
      print('生成图片缩略图出错: $e');
      return null;
    }
  }

  /// 使用 FFmpeg 压缩图片
  ///
  /// [inputPath] 原始图片路径
  /// [outputPath] 压缩后图片输出路径
  /// [maxWidth] 最大宽度,超过此宽度将等比缩放,默认1920
  /// [quality] JPEG 输出质量 (1-31,数值越小质量越高),默认18
  /// 返回是否压缩成功
  static Future<bool> compressImage(String inputPath, String outputPath, {int maxWidth = 1920, int quality = 18}) async {
    try {
      // 检查源文件是否存在
      final imageFile = File(inputPath);
      if (!await imageFile.exists()) {
        print('源图片文件不存在: $inputPath');
        return false;
      }

      // 构建 FFmpeg 命令行参数
      String cmd = '-i "$inputPath" ' // 指定输入文件路径
          '-vf "scale=min($maxWidth\\,iw):-1:flags=lanczos" ' // 等比缩放,宽度不超过maxWidth,使用Lanczos算法
          '-q:v $quality ' // 设置JPEG输出质量
          '-y ' // 覆盖已存在的输出文件
          '"$outputPath"'; // 指定输出文件路径

      // 执行 FFmpeg 命令
      final session = await FFmpegKit.execute(cmd);
      final returnCode = await session.getReturnCode();

      // 检查执行结果
      if (ReturnCode.isSuccess(returnCode)) {
        return true;
      } else {
        print('图片压缩失败: ${await session.getFailStackTrace()}');
        return false;
      }
    } catch (e) {
      print('图片压缩出错: $e');
      return false;
    }
  }
}