瀏覽代碼

[feat]添加计算图片容量的插件

Destiny 11 月之前
父節點
當前提交
db3bb91992

+ 30 - 25
lib/base/base_photo_controller.dart

@@ -45,10 +45,11 @@ abstract class BasePhotoController extends BaseController {
       return;
     }
 
-FileSizeCalculatorUtil.calculateTotalSize(assetIds: selectedPhotosIds, updateValue: (double totalSize) {
-      selectedFilesSize.value = totalSize; // 监听并更新 UI
-    });
-
+    FileSizeCalculatorUtil.calculateTotalSizeByIOS(
+        assetIds: selectedPhotosIds,
+        updateValue: (double totalSize) {
+          selectedFilesSize.value = totalSize; // 监听并更新 UI
+        });
   }
 
   // 切换图片选中状态
@@ -67,27 +68,31 @@ FileSizeCalculatorUtil.calculateTotalSize(assetIds: selectedPhotosIds, updateVal
     selectedFileCount.value = selectedPhotosIds.length;
 
     // 更新文件大小
-    if (selected) {
-      // 如果选中,增加文件大小
-      if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) {
-        selectedFilesSize.value += FileSizeCalculatorUtil.fileSizeCache[image.id]!;
-      } else {
-        final file = await image.file;
-        if (file != null) {
-          selectedFilesSize.value += (await file.length()) / 1024; // 转换为KB
-        }
-      }
-    } else {
-      // 如果取消选中,减少文件大小
-      if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) {
-        selectedFilesSize.value -= FileSizeCalculatorUtil.fileSizeCache[image.id]!;
-      } else {
-        final file = await image.file;
-        if (file != null) {
-          selectedFilesSize.value -= (await file.length()) / 1024; // 转换为KB
-        }
-      }
-    }
+    // if (selected) {
+    //   // 如果选中,增加文件大小
+    //   if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) {
+    //     selectedFilesSize.value +=
+    //         FileSizeCalculatorUtil.fileSizeCache[image.id]!;
+    //   } else {
+    //     final file = await image.file;
+    //     if (file != null) {
+    //       selectedFilesSize.value += (await file.length()) / 1024; // 转换为KB
+    //     }
+    //   }
+    // } else {
+    //   // 如果取消选中,减少文件大小
+    //   if (FileSizeCalculatorUtil.fileSizeCache.containsKey(image.id)) {
+    //     selectedFilesSize.value -=
+    //         FileSizeCalculatorUtil.fileSizeCache[image.id]!;
+    //   } else {
+    //     final file = await image.file;
+    //     if (file != null) {
+    //       selectedFilesSize.value -= (await file.length()) / 1024; // 转换为KB
+    //     }
+    //   }
+    // }
+
+    updateSelectedFilesSize();
 
     PhotoManager.clearFileCache();
   }

+ 1 - 1
lib/module/calendar/calendar_month_controller.dart

@@ -110,7 +110,7 @@ class CalendarMonthController extends BaseController {
       return;
     }
 
-    FileSizeCalculatorUtil.calculateTotalSize(
+    FileSizeCalculatorUtil.calculateTotalSizeByIOS(
       assetIds: photoGroup.value.selectedPhotosIds,
       updateValue: (double totalSize) {
         photoGroup.value.selectedTotalSize.value = totalSize;

+ 1 - 1
lib/module/calendar/preview/calendar_preview_controller.dart

@@ -260,7 +260,7 @@ class CalendarPreviewController extends BaseController
       return;
     }
 
-    FileSizeCalculatorUtil.calculateTotalSize(
+    FileSizeCalculatorUtil.calculateTotalSizeByIOS(
       assetIds: photoGroup.value.selectedPhotosIds,
       updateValue: (double totalSize) {
         photoGroup.value.selectedTotalSize.value = totalSize;

+ 1 - 1
lib/module/calendar/selected_preview/calendar_selected_preview_controller.dart

@@ -138,7 +138,7 @@ class CalendarSelectedPreviewController extends BaseController {
       return;
     }
 
-    FileSizeCalculatorUtil.calculateTotalSize(
+    FileSizeCalculatorUtil.calculateTotalSizeByIOS(
       assetIds: photoGroup.value.selectedPhotosIds,
       updateValue: (double totalSize) {
         photoGroup.value.selectedTotalSize.value = totalSize;

+ 1 - 1
lib/module/image_picker/image_picker_util.dart

@@ -311,7 +311,7 @@ class ImagePickerUtil {
     if (androidPhotos.isNotEmpty) return androidPhotos;
     // 选择相册
     final List<AssetPathEntity> albums = await PhotoManager.getAssetPathList(
-      type: RequestType.image,
+      type: RequestType.common,
       filterOption: FilterOptionGroup(
         orders: [
           // 根据创建日期排序,降序(最新的在前)

+ 1 - 1
lib/module/photo_preview/photo_preview_controller.dart

@@ -193,7 +193,7 @@ class PhotoPreviewController extends BaseController
       selectedFilesSize.value = 0;
       return;
     }
-    FileSizeCalculatorUtil.calculateTotalSize(
+    FileSizeCalculatorUtil.calculateTotalSizeByIOS(
       assetIds: selectedPhotosIds,
       updateValue: (double totalSize) {
         selectedFilesSize.value = totalSize;

+ 14 - 0
lib/utils/file_size_calculator_util.dart

@@ -1,5 +1,6 @@
 import 'dart:ffi';
 
+import 'package:classify_photo/classify_photo.dart';
 import 'package:flutter/cupertino.dart';
 import 'package:wechat_assets_picker/wechat_assets_picker.dart';
 import 'package:photo_manager/photo_manager.dart';
@@ -7,6 +8,19 @@ import 'package:photo_manager/photo_manager.dart';
 class FileSizeCalculatorUtil {
   static final Map<String, double> fileSizeCache = {};
 
+  static Future<void> calculateTotalSizeByIOS({
+    required Set<String> assetIds,
+    required Function(double) updateValue,
+  }) async {
+    if (assetIds.isEmpty) {
+      updateValue(0);
+      return;
+    }
+    double totalSize = 0;
+    totalSize = await ClassifyPhoto().calculatePhotosSize(assetIds.toList()) / 1024;
+    updateValue(totalSize);
+  }
+
   static Future<void> calculateTotalSize({
     required Set<String> assetIds,
     required Function(double) updateValue,

+ 2 - 2
plugins/classify_photo/ios/Classes/ClassifyPhoto.swift

@@ -543,7 +543,7 @@ class ClassifyPhoto {
 extension ClassifyPhoto {
     
     // 获取资源大小的辅助方法
-    private func getAssetSize(_ asset: PHAsset, completion: @escaping (Int64) -> Void) {
+    func getAssetSize(_ asset: PHAsset, completion: @escaping (Int64) -> Void) {
         let resources = PHAssetResource.assetResources(for: asset)
         if let resource = resources.first {
             var size: Int64 = 0
@@ -557,7 +557,7 @@ extension ClassifyPhoto {
     }
 
     // 计算资产组的总大小
-    private func calculateAssetsSize(_ assets: [PHAsset], completion: @escaping (PhotoSizeInfo) -> Void) {
+    func calculateAssetsSize(_ assets: [PHAsset], completion: @escaping (PhotoSizeInfo) -> Void) {
         let group = DispatchGroup()
         var totalSize: Int64 = 0
         

+ 37 - 10
plugins/classify_photo/ios/Classes/ClassifyPhotoPlugin.swift

@@ -20,16 +20,6 @@ public class ClassifyPhotoPlugin: NSObject, FlutterPlugin {
         self.getPhoto(flutterResult: result)
     case "getStorageInfo":
         getStorageInfo(result: result)
-//    case "checkTrialEligibility":
-//        if #available(iOS 15.0, *) {
-//            Task {
-//                let handler = SubscriptionHandler()
-//                let isEligible = await handler.checkTrialEligibility()
-//                DispatchQueue.main.async {
-//                    result(isEligible)
-//                }
-//            }
-//        }
     case "getExifInfo":
         guard let args = call.arguments as? [String: Any],
               let filePath = args["filePath"] as? String else {
@@ -41,6 +31,17 @@ public class ClassifyPhotoPlugin: NSObject, FlutterPlugin {
             return
         }
         getExifInfo(filePath: filePath, completion: result)
+    case "getPhotosSize":
+        guard let args = call.arguments as? [String: Any],
+              let assetIds = args["assetIds"] as? [String] else {
+            result(FlutterError(
+                code: "INVALID_ARGUMENTS",
+                message: "Missing filePath parameter",
+                details: nil
+            ))
+            return
+        }
+        calculatePhotosSize(assetIds: assetIds, completion: result)
     case "getPlatformVersion":
         result("iOS " + UIDevice.current.systemVersion)
     default:
@@ -307,6 +308,32 @@ public class ClassifyPhotoPlugin: NSObject, FlutterPlugin {
         }
 }
 
+// 计算选择的图片大小
+extension ClassifyPhotoPlugin {
+    
+    private func calculatePhotosSize(assetIds: [String], completion: @escaping FlutterResult) {
+        let assets = PHAsset.fetchAssets(withLocalIdentifiers: assetIds, options: nil)
+        var phAssets: [PHAsset] = []
+        var sizes: Int64 = 0 // 用于存储文件大小
+        
+        assets.enumerateObjects { (phAsset, _, _) in
+            phAssets.append(phAsset)
+            
+            // 获取 PHAsset 的资源
+            let resources = PHAssetResource.assetResources(for: phAsset)
+            if let resource = resources.first {
+                // 获取文件大小
+                if let unsignedInt64 = resource.value(forKey: "fileSize") as? CLong {
+                    sizes += Int64(unsignedInt64)
+                }
+            }
+        }
+        
+        // 返回文件大小到 Flutter
+        completion(sizes)
+    }
+}
+
 
 class SubscriptionHandler: NSObject {
     

+ 4 - 0
plugins/classify_photo/lib/classify_photo.dart

@@ -32,4 +32,8 @@ class ClassifyPhoto {
   Future<void> finishTransaction() {
     return ClassifyPhotoPlatform.instance.finishTransaction();
   }
+
+  Future<int> calculatePhotosSize(List<String> assetIds) {
+    return ClassifyPhotoPlatform.instance.calculatePhotoSize(assetIds);
+  }
 }

+ 16 - 0
plugins/classify_photo/lib/classify_photo_method_channel.dart

@@ -110,4 +110,20 @@ class MethodChannelClassifyPhoto extends ClassifyPhotoPlatform {
     print('Flutter: 清除自动订阅记录');
     await methodChannel.invokeMethod<Map<dynamic, dynamic>>('finishTran');
   }
+
+  @override
+  Future<int> calculatePhotoSize(List<String> assetIds) async {
+    try {
+      final result = await methodChannel.invokeMethod<int>(
+        'getPhotosSize',
+        {'assetIds': assetIds},
+      );
+
+      // 转换结果为 Map<String, dynamic>
+      return result ?? 0;
+    } catch (e) {
+      print('获取照片容量大小错误: $e');
+      return 0;
+    }
+  }
 }

+ 4 - 0
plugins/classify_photo/lib/classify_photo_platform_interface.dart

@@ -51,4 +51,8 @@ abstract class ClassifyPhotoPlatform extends PlatformInterface {
   Future<void> finishTransaction() {
     throw UnimplementedError('finishTransaction() has not been implemented.');
   }
+
+  Future<int> calculatePhotoSize(List<String> assetIds) {
+    throw UnimplementedError('finishTransaction() has not been implemented.');
+  }
 }

+ 1 - 1
pubspec.yaml

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 # In Windows, build-name is used as the major, minor, and patch parts
 # of the product and file versions while build-number is used as the build suffix.
-version: 1.1.0+18
+version: 1.1.0+19
 
 environment:
   sdk: ^3.6.0