photo_scan_handler.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import 'dart:io';
  2. import 'package:classify_photo/classify_photo.dart';
  3. import 'package:get/get.dart';
  4. import 'package:permission_handler/permission_handler.dart';
  5. import 'package:wechat_assets_picker/wechat_assets_picker.dart';
  6. import '../../module/image_picker/image_picker_util.dart';
  7. import '../utils/toast_util.dart';
  8. class PhotoScanHandler {
  9. static final _photoClassify = ClassifyPhoto();
  10. static RxBool isSimilarScanned = false.obs;
  11. static RxBool isPeopleScanned = false.obs;
  12. static RxBool isScreenShotScanned = false.obs;
  13. static RxBool isBlurryScanned = false.obs;
  14. // 人物图片
  15. static RxList<AssetEntity> peoplePhotos = <AssetEntity>[].obs;
  16. // 地点图片
  17. static Rx<AssetEntity?> locationPhoto = Rx<AssetEntity?>(null);
  18. // 截图照片
  19. static Rx<AssetEntity?> screenshotPhoto = Rx<AssetEntity?>(null);
  20. // 模糊照片
  21. static Rx<AssetEntity?> blurryPhoto = Rx<AssetEntity?>(null);
  22. // 相似照片
  23. static RxList<AssetEntity> similarPhotos = <AssetEntity>[].obs;
  24. /// 执行所有的照片处理操作
  25. static Future<void> handleAllPhotos() async {
  26. var request = Platform.isIOS
  27. ? await Permission.photos.request()
  28. : await Permission.storage.request();
  29. if (request.isGranted) {
  30. PhotoManager.clearFileCache();
  31. await handleScreenPhotos();
  32. await handleBlurryPhotos();
  33. await handlePeoplePhotos();
  34. await handleSimilarPhotos();
  35. if (Platform.isAndroid) {
  36. await handleAndroidPhotos();
  37. }
  38. } else if (request.isPermanentlyDenied) {
  39. ToastUtil.show("Please enable the album permission");
  40. openAppSettings();
  41. } else {
  42. ToastUtil.show("Please enable the album permission");
  43. isSimilarScanned.value = false;
  44. isPeopleScanned.value = false;
  45. isBlurryScanned.value = false;
  46. isScreenShotScanned.value = false;
  47. }
  48. }
  49. /// 截图照片
  50. static Future<bool> handleScreenPhotos() async {
  51. try {
  52. final photos = await _photoClassify.getScreenshots();
  53. print('获取截图照片完成: ${photos?.length ?? 0} 组照片');
  54. isScreenShotScanned.value = true;
  55. if (photos != null) {
  56. await ImagePickerUtil.updatePhotos(photos);
  57. if (ImagePickerUtil.screenshotPhotos.isNotEmpty) {
  58. var asset = ImagePickerUtil.screenshotPhotos.first;
  59. screenshotPhoto.value = asset;
  60. }
  61. }
  62. } catch (e, stackTrace) {
  63. print('获取截图失败: $e\n$stackTrace');
  64. }
  65. isScreenShotScanned.value = true;
  66. return true;
  67. }
  68. /// 模糊照片
  69. static Future<bool> handleBlurryPhotos() async {
  70. try {
  71. final photos = await _photoClassify.getBlurryPhotos();
  72. print('获取模糊照片完成: ${photos?.length ?? 0} 组照片');
  73. isBlurryScanned.value = true;
  74. if (photos != null) {
  75. await ImagePickerUtil.updatePhotos(photos);
  76. if (ImagePickerUtil.blurryPhotos.isNotEmpty) {
  77. var asset = ImagePickerUtil.blurryPhotos.first;
  78. blurryPhoto.value = asset;
  79. }
  80. return true;
  81. }
  82. } catch (e, stackTrace) {
  83. print('获取模糊失败: $e\n$stackTrace');
  84. }
  85. isBlurryScanned.value = true;
  86. return true;
  87. }
  88. /// 人物照片
  89. static Future<bool> handlePeoplePhotos() async {
  90. try {
  91. final photos = await _photoClassify.getPeoplePhotos();
  92. print('获取人物照片完成: ${photos?.length ?? 0} 组照片');
  93. isPeopleScanned.value = true;
  94. if (photos != null) {
  95. await ImagePickerUtil.updatePhotos(photos);
  96. // 处理人物照片
  97. peoplePhotos.clear();
  98. if (ImagePickerUtil.peoplePhotos.isNotEmpty) {
  99. for (var personPhotos in ImagePickerUtil.peoplePhotos) {
  100. peoplePhotos.add(personPhotos);
  101. if (peoplePhotos.length == 2) {
  102. break;
  103. }
  104. }
  105. }
  106. return true;
  107. }
  108. } catch (e, stackTrace) {
  109. print('获取人物失败: $e\n$stackTrace');
  110. }
  111. isPeopleScanned.value = true;
  112. return true;
  113. }
  114. /// 相似照片
  115. static Future<bool> handleSimilarPhotos() async {
  116. try {
  117. print('开始获取相似照片');
  118. final photos = await _photoClassify.getSimilarPhotos();
  119. print('获取相似照片完成: ${photos?.length ?? 0} 组照片');
  120. isSimilarScanned.value = true;
  121. if (photos != null) {
  122. await ImagePickerUtil.updatePhotos(photos);
  123. similarPhotos.clear();
  124. if (ImagePickerUtil.similarPhotos.isNotEmpty) {
  125. for (var group in ImagePickerUtil.similarPhotos) {
  126. for (var asset in group) {
  127. similarPhotos.add(asset);
  128. if (similarPhotos.length == 4) {
  129. break;
  130. }
  131. }
  132. }
  133. }
  134. return true;
  135. }
  136. } catch (e, stackTrace) {
  137. print('获取相似失败: $e\n$stackTrace');
  138. }
  139. isSimilarScanned.value = true;
  140. return true;
  141. }
  142. /// Android平台处理方式
  143. static Future<void> handleAndroidPhotos() async {
  144. final List<AssetEntity> result = await ImagePickerUtil.loadAssets();
  145. ImagePickerUtil.peoplePhotos.value = result ?? [];
  146. ImagePickerUtil.locationPhotos['location'] = result ?? [];
  147. ImagePickerUtil.screenshotPhotos.value = result ?? [];
  148. const int batchSize = 10;
  149. for (int i = 0; i < result.length; i += batchSize) {
  150. int end = (i + batchSize < result.length) ? i + batchSize : result.length;
  151. List<AssetEntity> batch = result.sublist(i, end);
  152. ImagePickerUtil.similarPhotos.add(batch);
  153. }
  154. ImagePickerUtil.blurryPhotos.value = result ?? [];
  155. print("handleAndroidPhotos $result");
  156. print(
  157. "ImagePickerUtil.peoplePhotos.value ${ImagePickerUtil.peoplePhotos.length}");
  158. isSimilarScanned.value = true;
  159. isPeopleScanned.value = true;
  160. isBlurryScanned.value = true;
  161. isScreenShotScanned.value = true;
  162. similarPhotos.clear();
  163. if (ImagePickerUtil.similarPhotos.isNotEmpty) {
  164. for (var group in ImagePickerUtil.similarPhotos) {
  165. print(
  166. " ImagePickerUtil.similarPhotos ${ImagePickerUtil.similarPhotos.length}");
  167. for (var asset in group) {
  168. similarPhotos.add(asset);
  169. if (similarPhotos.length == 4) {
  170. break;
  171. }
  172. }
  173. }
  174. }
  175. peoplePhotos.clear();
  176. if (ImagePickerUtil.peoplePhotos.isNotEmpty) {
  177. for (var personPhotos in ImagePickerUtil.peoplePhotos) {
  178. peoplePhotos.add(personPhotos);
  179. if (peoplePhotos.length == 2) {
  180. break;
  181. }
  182. }
  183. }
  184. if (ImagePickerUtil.blurryPhotos.isNotEmpty) {
  185. var asset = ImagePickerUtil.blurryPhotos.first;
  186. blurryPhoto.value = asset;
  187. }
  188. if (ImagePickerUtil.screenshotPhotos.isNotEmpty) {
  189. var asset = ImagePickerUtil.screenshotPhotos.first;
  190. screenshotPhoto.value = asset;
  191. }
  192. }
  193. }