import 'dart:io'; import 'dart:typed_data'; import 'package:clean/model/asset_info.dart'; import 'package:clean/module/image_picker/image_picker_util.dart'; import 'package:clean/utils/toast_util.dart'; import 'package:intl/intl.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'file_utils.dart'; import 'package:exif/exif.dart'; class ImageUtil { // 生成月份 key (用于内部存储) static String getMonthKey(DateTime date) { return '${date.year}-${date.month.toString().padLeft(2, '0')}'; } // 格式化月份显示 (例如: Jan 2025) static String formatMonthKey(String monthKey) { final parts = monthKey.split('-'); if (parts.length == 2) { final date = DateTime(int.parse(parts[0]), int.parse(parts[1])); return DateFormat('MMM yyyy').format(date); } return monthKey; } // 获取指定索引的月份显示文本 static String getMonthText(Map> assets, int index) { final monthKeys = assets.keys.toList() ..sort((a, b) => b.compareTo(a)); // 最新的月份在前 if (index < monthKeys.length) { return formatMonthKey(monthKeys[index]); } return ''; } // 获取指定月份的图片 static List getMonthAssets( Map> assets, int index) { final monthKeys = assets.keys.toList() ..sort((a, b) => b.compareTo(a)); // 最新的月份在前 if (index < monthKeys.length) { return assets[monthKeys[index]] ?? []; } return []; } // 获取缩略图数据 static Future getImageThumbnail( FileType type, AssetInfo asset) async { try { // 先尝试从本地读取缩略图 final localThumb = await FileUtils.getThumbData( type, Platform.isIOS ? asset.id.substring(0, 36) : asset.id); if (localThumb != null) { return localThumb; } // 如果本地没有,则从 AssetEntity 获取 return await asset.thumbnailData; } catch (e) { print('获取缩略图失败: $e'); return null; } } // 获取原始图片文件 static Future getImageFile(FileType type, AssetInfo asset) async { try { // 先尝试从本地读取 final assetPath = await FileUtils.getAssetPath(type); final localFile = File( '$assetPath/${Platform.isIOS ? asset.id.substring(0, 36) : asset.id}.PNG'); if (await localFile.exists()) { return localFile; } // 如果本地没有,则从 AssetEntity 获取 return asset.file; } catch (e) { print('获取图片文件失败: $e'); return null; } } static Future> getPhotoDetails(AssetInfo asset) async { try { final Map details = {}; var title = ""; if (asset.originalPath != null) { // 查找 "o_" 的位置 final int index = asset.originalPath!.lastIndexOf('_o_'); if (index != -1) { // 截取 "o_" 后面的字符串 title = asset.originalPath!.substring(index + 3); } else { // 如果没有找到 "o_",返回原始文件名 title = asset.originalPath!.split('/').last; } } // 基本信息 details['fileName'] = title; // 创建格式化器 final formatter = DateFormat('yyyy-MM-dd EEE HH:mm'); details['createDate'] = formatter.format(asset.createDateTime); details['width'] = asset.width; details['height'] = asset.height; details['size'] = asset.size; // 获取文件 final path = asset.originalPath; // final file = await asset.file; if (path != null && path.isNotEmpty) { try { final file = File(path); // 读取 EXIF 数据 final bytes = await file.readAsBytes(); final exifData = await readExifFromBytes(bytes); if (exifData.isNotEmpty) { // 相机信息 details['make'] = exifData['Image Make']?.printable; details['model'] = exifData['Image Model']?.printable; // 拍摄参数 // 光圈值 details['aperture'] = exifData['EXIF FNumber']?.printable; // 快门速度/曝光时间 details['exposureTime'] = exifData['EXIF ExposureTime']?.printable; // ISO感光度 details['iso'] = exifData['EXIF ISOSpeedRatings']?.printable; // 焦距 details['focalLength'] = exifData['EXIF FocalLengthIn35mmFilm']?.printable; // GPS 信息 if (exifData.containsKey('GPS GPSLatitude') && exifData.containsKey('GPS GPSLongitude')) { details['latitude'] = exifData['GPS GPSLatitude']?.printable; details['longitude'] = exifData['GPS GPSLongitude']?.printable; } } } catch (e) { print('读取 EXIF 数据失败: $e'); ToastUtil.show('Failed to get photo details'); } } print(details); return details; } catch (e) { print('Failed to get photo details: $e'); return {}; } } /// 格式化图片尺寸 static String formatResolution(int width, int height) { final megapixels = (width * height) / 1000000.0; if (megapixels >= 1) { return '${megapixels.toStringAsFixed(1)} MP ($width × $height)'; } else { return '$width × $height'; } } /// 格式化文件大小 static String formatFileSize(int bytes) { if (bytes < 1024) return '$bytes B'; if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB'; if (bytes < 1024 * 1024 * 1024) { return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB'; } return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB'; } /// 格式化光圈值 static String formatAperture(String? value) { if (value == null) return 'Unknown'; return 'f/$value'; } /// 格式化曝光时间 static String formatExposureTime(String? value) { if (value == null) return 'Unknown'; // 将分数转换为更易读的格式 if (value.contains('/')) { final parts = value.split('/'); if (parts.length == 2) { final numerator = int.parse(parts[0]); final denominator = int.parse(parts[1]); if (numerator == 1) { return '1/${denominator}s'; } } } return '${value}s'; } }