Commit 76e48012 by tanghuan

上传文件到OBS时,对图片进行压缩后再上传

1 parent 9587dbe0
...@@ -7,6 +7,7 @@ import 'package:appframe/config/locator.dart'; ...@@ -7,6 +7,7 @@ import 'package:appframe/config/locator.dart';
import 'package:appframe/services/api_service.dart'; import 'package:appframe/services/api_service.dart';
import 'package:appframe/services/dispatcher.dart'; import 'package:appframe/services/dispatcher.dart';
import 'package:appframe/utils/file_type_util.dart'; import 'package:appframe/utils/file_type_util.dart';
import 'package:appframe/utils/image_util.dart';
import 'package:appframe/utils/video_util.dart'; import 'package:appframe/utils/video_util.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -77,7 +78,7 @@ class UploadFileHandler extends MessageHandler { ...@@ -77,7 +78,7 @@ class UploadFileHandler extends MessageHandler {
/// 非 mp4 格式的视频文件需先转码 /// 非 mp4 格式的视频文件需先转码
/// ///
String? mimeType = await FileTypeUtil.getMimeType(file); String? mimeType = await FileTypeUtil.getMimeType(file);
if (mimeType?.startsWith('video/') ?? false) { if (mimeType?.toLowerCase().startsWith('video/') ?? false) {
final inputPath = filePath; final inputPath = filePath;
final tempDir = await getTemporaryDirectory(); final tempDir = await getTemporaryDirectory();
final outputPath = '${tempDir.path}/${Uuid().v4()}.mp4'; final outputPath = '${tempDir.path}/${Uuid().v4()}.mp4';
...@@ -93,6 +94,22 @@ class UploadFileHandler extends MessageHandler { ...@@ -93,6 +94,22 @@ class UploadFileHandler extends MessageHandler {
file = File(outputPath); file = File(outputPath);
fileSize = file.lengthSync(); fileSize = file.lengthSync();
} else if (mimeType?.toLowerCase().startsWith('image/') ?? false) { // 对于图片文件,进行压缩
// 对于图片文件,进行压缩
final inputPath = filePath;
final tempDir = await getTemporaryDirectory();
final outputPath = '${tempDir.path}/${Uuid().v4()}.jpg';
var startTime = DateTime.now();
final success = await ImageUtil.compressImage(inputPath, outputPath, maxWidth: 1920, quality: 18);
var endTime = DateTime.now();
print('====================>图片压缩耗时:${endTime.millisecondsSinceEpoch - startTime.millisecondsSinceEpoch} 毫秒');
if (success) {
file = File(outputPath);
fileSize = file.lengthSync();
print('====================>图片压缩后大小:$fileSize 字节');
}
} }
/// 2 /// 2
......
...@@ -5,12 +5,12 @@ import 'package:mime/mime.dart'; ...@@ -5,12 +5,12 @@ import 'package:mime/mime.dart';
class FileTypeUtil { class FileTypeUtil {
static Future<bool> isImage(File file) async { static Future<bool> isImage(File file) async {
var mimeType = await getMimeType(file); var mimeType = await getMimeType(file);
return mimeType?.startsWith('image/') ?? false; return mimeType?.toLowerCase().startsWith('image/') ?? false;
} }
static Future<bool> isVideo(File file) async { static Future<bool> isVideo(File file) async {
var mimeType = await getMimeType(file); var mimeType = await getMimeType(file);
return mimeType?.startsWith('video/') ?? false; return mimeType?.toLowerCase().startsWith('video/') ?? false;
} }
static Future<String?> getMimeType(File file) async { static Future<String?> getMimeType(File file) async {
......
...@@ -49,4 +49,44 @@ class ImageUtil { ...@@ -49,4 +49,44 @@ class ImageUtil {
return null; 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;
}
}
} }
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!