image_picker_util.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import 'dart:io';
  2. import 'dart:math';
  3. import 'package:clean/model/asset_group.dart';
  4. import 'package:clean/module/people_photo/photo_group.dart';
  5. import 'package:get/get.dart';
  6. import 'package:photo_manager/photo_manager.dart';
  7. class ImagePickerUtil {
  8. ImagePickerUtil._();
  9. static const RequestType permissionType = RequestType.image;
  10. static final RxInt similarPhotoCount = 0.obs;
  11. // 全局存储不同类型的照片
  12. // 截图图片
  13. static final RxList<AssetEntity> screenshotPhotos = <AssetEntity>[].obs;
  14. // 模糊图片
  15. static final RxList<AssetEntity> blurryPhotos = <AssetEntity>[].obs;
  16. // 相似图片
  17. static final RxList<List<AssetEntity>> similarPhotos =
  18. <List<AssetEntity>>[].obs;
  19. // 地点图片
  20. static final RxMap<String, List<AssetEntity>> locationPhotos =
  21. <String, List<AssetEntity>>{}.obs;
  22. // 人物图片
  23. static final RxList<AssetEntity> peoplePhotos = <AssetEntity>[].obs;
  24. static final RxSet<String> selectedScreenshotPhotosIds = <String>{}.obs;
  25. static final RxSet<String> selectedSimilarPhotosIds = <String>{}.obs;
  26. static final RxSet<String> selectedLocationPhotosIds = <String>{}.obs;
  27. static final RxSet<String> selectedPeoplePhotosIds = <String>{}.obs;
  28. static final RxSet<String> selectedBlurryPhotosIds = <String>{}.obs;
  29. // 添加大小信息的变量
  30. static final Rx<int> screenshotsSize = 0.obs;
  31. static final Rx<int> blurrySize = 0.obs;
  32. static final Rx<int> locationsSize = 0.obs;
  33. static final Rx<int> peopleSize = 0.obs;
  34. static final Rx<int> similarPhotosSize = 0.obs;
  35. // 清除所有照片数据
  36. static void clearAllPhotos() {
  37. similarPhotoCount.value = 0;
  38. screenshotPhotos.clear();
  39. blurryPhotos.clear();
  40. similarPhotos.clear();
  41. locationPhotos.clear();
  42. peoplePhotos.clear();
  43. }
  44. // 更新照片数据
  45. static Future<void> updatePhotos(
  46. List<Map<String, dynamic>> photoGroups) async {
  47. clearAllPhotos();
  48. for (var group in photoGroups) {
  49. String type = group['type'] as String;
  50. Map<dynamic, dynamic> groupData = group['group'] as Map<dynamic, dynamic>;
  51. List<dynamic> photos = groupData['photos'] as List<dynamic>;
  52. int totalSize = groupData['totalSize'] as int;
  53. int count = groupData['count'] as int;
  54. switch (type) {
  55. case 'screenshots':
  56. screenshotPhotos.value = await _convertToAssetEntities(photos);
  57. screenshotsSize.value = totalSize;
  58. break;
  59. case 'similar':
  60. similarPhotos.add(await _convertToAssetEntities(photos));
  61. similarPhotosSize.value = totalSize;
  62. similarPhotoCount.value = count;
  63. break;
  64. case 'location':
  65. String location = group['name'] as String;
  66. locationPhotos[location] = await _convertToAssetEntities(photos);
  67. locationsSize.value = totalSize;
  68. break;
  69. case 'people':
  70. peoplePhotos.value = await _convertToAssetEntities(photos);
  71. peopleSize.value = totalSize;
  72. break;
  73. case 'blurry':
  74. blurryPhotos.value = await _convertToAssetEntities(photos);
  75. blurrySize.value = totalSize;
  76. break;
  77. }
  78. }
  79. }
  80. // 将原始照片数据转换为 AssetEntity 列表
  81. static Future<List<AssetEntity>> _convertToAssetEntities(
  82. List<dynamic> photos) async {
  83. List<AssetEntity> entities = [];
  84. for (var photo in photos) {
  85. final entity = await AssetEntity.fromId(photo['id'] as String);
  86. if (entity != null) {
  87. entities.add(entity);
  88. }
  89. }
  90. return entities;
  91. }
  92. //申请权限
  93. static Future<bool> requestPermissionExtend() async {
  94. final PermissionState ps = await PhotoManager.requestPermissionExtend(
  95. requestOption: const PermissionRequestOption(
  96. androidPermission: AndroidPermission(
  97. type: permissionType,
  98. mediaLocation: false,
  99. )));
  100. return ps.hasAccess;
  101. }
  102. //判断是否有权限
  103. static Future<bool> hasPermission() async {
  104. final PermissionState ps = await PhotoManager.getPermissionState(
  105. requestOption: const PermissionRequestOption(
  106. androidPermission: AndroidPermission(
  107. type: permissionType,
  108. mediaLocation: false,
  109. )));
  110. return ps.hasAccess;
  111. }
  112. static String formatFileSize(int bytes, {int decimals = 2}) {
  113. if (bytes <= 0) return '0 B';
  114. const suffixes = ['B', 'KB', 'MB', 'GB', 'TB'];
  115. var i = (log(bytes) / log(1024)).floor();
  116. // 确保不超过数组范围
  117. i = i < suffixes.length ? i : suffixes.length - 1;
  118. // 计算实际大小
  119. final size = bytes / pow(1024, i);
  120. // 格式化数字,处理小数点位数
  121. String sizeStr;
  122. if (size >= 100) {
  123. // 大于100的只保留整数
  124. sizeStr = size.round().toString();
  125. } else {
  126. // 小于100的保留指定小数位
  127. sizeStr = size.toStringAsFixed(decimals);
  128. }
  129. // 移除末尾的0和不必要的小数点
  130. sizeStr = sizeStr.replaceAll(RegExp(r'\.?0+$'), '');
  131. return '$sizeStr ${suffixes[i]}';
  132. }
  133. /// 直接转换为 GB 单位
  134. static String formatToGB(int bytes, {int decimals = 2}) {
  135. if (bytes <= 0) return '0 GB';
  136. final gb = bytes / pow(1024, 3); // 直接转换为 GB
  137. // 格式化数字,处理小数点位数
  138. String sizeStr;
  139. if (gb >= 100) {
  140. // 大于100的只保留整数
  141. sizeStr = gb.round().toString();
  142. } else {
  143. // 小于100的保留指定小数位
  144. sizeStr = gb.toStringAsFixed(decimals);
  145. }
  146. // 移除末尾的0和不必要的小数点
  147. sizeStr = sizeStr.replaceAll(RegExp(r'\.?0+$'), '');
  148. return '$sizeStr GB';
  149. }
  150. /// 格式化存储大小
  151. static String formatSize(double sizeInGB) {
  152. if (sizeInGB < 0.001) { // 小于 1MB
  153. return '${(sizeInGB * 1024 * 1024).toStringAsFixed(1)} ';
  154. } else if (sizeInGB < 1) { // 小于 1GB
  155. return '${(sizeInGB * 1024).toStringAsFixed(1)} ';
  156. } else if (sizeInGB < 1024) { // 小于 1TB
  157. return '${sizeInGB.toStringAsFixed(1)} ';
  158. } else { // 大于等于 1TB
  159. return '${(sizeInGB / 1024).toStringAsFixed(1)} ';
  160. }
  161. }
  162. }