iOS 實現圖庫多張圖片的選擇原理

相信大家對單張圖片的選擇都比較熟悉,簡單的UIImagePickerController就實現了

但是,這裏多張圖片實現就相對比較麻煩,先簡單的展示一下我們最終要實現的效果






AssetsLibrary和PhotoKit框架都可以用來封裝相冊的單選與多選功能,不過ALAssetLibrary的方法在iOS 9中不被推薦了,現在都是用新的框架PhotoKit

的來實現。發現好多之前的應用自定義的XXImagePickerController都無法獲取到所有的照片了,爲了能讓老程序也可以實現這時候就要使用AssetsLibrary+Photos來解決問題了。

正因爲蘋果已經做了大量的封裝工作,使得開發者在使用PhotoKit的時候非常方便。

先簡單介紹下ALAssetsLibrary:

ALAssetsLibrary 提供了訪問iOS設備下照片應用下所有照片和視頻的接口.從 ALAssetsLibrary 中可讀取所有的相冊數據,即 ALAssetsGroup 對象列表; 從每個 ALAssetsGroup 中可獲取到其中包含的照片或視頻列表,即 ALAsset 對象列表. 其層次關係爲  

ALAssetsLibrary -> ALAssetsGroup -> ALAsset -> ALAssetRepresentation. 
1) ALAssetsLibrary類:
ALAssetsLibrary類可以實現查看相冊列表,增加相冊,保存圖片到相冊等功能。
例如enumerateGroupsWithTypes方法列舉所有相冊。

(2) ALAssetsGroup
*ALAssetsGroup就是相冊的類,可以通過valueForProperty方法查看不同屬性的值,如:ALAssetsGroupPropertyName,相冊名。
*ALAssetsGroup類有幾個方法,posterImage方法就是相冊的封面圖片,numberOfAssets方法獲取該相冊的圖片視頻數量,可以通過enumerateAssetsUsingBlock方法列舉出所有照片。
*ALAssetsGroup 可以使用setAssetsFilter:(ALAssetsFilter *)filter過濾照片或者視頻等。
首先是獲取所有相冊,通過ALAssetsLibrary的實例方法得到ALAssetsGroup類數組。
複製代碼
   ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
    NSMutableArray *groupArray = [NSMutableArray array];
    [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
        if (group) {
            [groupArray addObject:group];
            
            //通過這個可以知道相冊的名字,從而也可以知道安裝的部分應用
            NSLog(@"%@",group);
        }
    } failureBlock:^(NSError *error) {
        NSLog(@"Group not found!\n");
    }];
複製代碼
(3) ALAsset
*ALAsset類也可以通過valueForProperty方法查看不同屬性的值,如:ALAssetPropertyType,asset的類型,有三種ALAssetTypePhoto, ALAssetTypeVideo or ALAssetTypeUnknown。
*另外還可以通過該方法獲取ALAssetPropertyLocation(照片位置),ALAssetPropertyDuration(視頻時間),ALAssetPropertyDate(照片拍攝日期)等。
可以通過thumbnail方法就是獲取該照片。
*根據相冊獲取該相冊下所有圖片,通過ALAssetsGroup的實例方法得到ALAsset類數組。
複製代碼
 [_group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
        if (result) {
            [imageArray addObject:result];
            NSLog(@"%@",result);
             iv.image=[UIImage imageWithCGImage: result.thumbnail];
NSString *type=[result valueForProperty:ALAssetPropertyType];
        }
    }];
複製代碼

(4) ALAssetsFilter:提供過濾照片或者視頻的實例等。

(5) ALAssetRepresentation
ALAsset類有一個defaultRepresentation方法,返回值是ALAssetRepresentation類,該類的作用就是獲取該資源圖片的詳細資源信息。
複製代碼
//
//獲取資源圖片的詳細資源信息
ALAssetRepresentation* representation = [asset defaultRepresentation];
//獲取資源圖片的長寬
CGSize dimension = [representation dimensions];
 //獲取資源圖片的高清圖
[representation fullResolutionImage];
//獲取資源圖片的全屏圖
[representation fullScreenImage];
//獲取資源圖片的名字
NSString* filename = [representation filename];
NSLog(@"filename:%@",filename);
//縮放倍數
[representation scale];
//圖片資源容量大小
[representation size];
//圖片資源原數據
 [representation metadata];
//旋轉方向
[representation orientation];
 //資源圖片url地址,該地址和ALAsset通過ALAssetPropertyAssetURL獲取的url地址是一樣的
NSURL* url = [representation url];
NSLog(@"url:%@",url);
//資源圖片uti,唯一標示符
NSLog(@"uti:%@",[representation UTI]);


       1、每個ALAsset 可能有多個representations表示, 即ALAssetRepresentation 對象;
       
       2、使用其defaultRepresentation 方法可獲得其默認representations;

       3、使用[asset valueForProperty: ALAssetPropertyRepresentations ]可獲取其所有representations的 UTI 數組;

       4、從ALAsset對象可獲取縮略圖 thumbnail 或 aspectRatioThumbnail ; 

再簡單介紹一下photoKit的框架。photoKit的基本構成有:

     1、PHAsset: 代表照片庫中的一個資源,跟 ALAsset 類似,通過 PHAsset 可以獲取和保存資源

     2、PHFetchOptions: 獲取資源時的參數,可以傳 nil,即使用系統默認值

     3、PHAssetCollection: PHCollection 的子類,表示一個相冊或者一個時刻,或者是一個「智能相冊(系統提供的特定的一系列相冊,例如:最近刪

除,視頻列表,收藏等等,如下圖所示)

     4、PHFetchResult: 表示一系列的資源結果集合,也可以是相冊的集合,從 PHCollection 的類方法中獲得

     5、PHImageManager: 用於處理資源的加載,加載圖片的過程帶有緩存處理,可以通過傳入一個 PHImageRequestOptions 控制資源的輸出尺寸等規格

PHImageRequestOptions: 如上面所說,控制加載圖片時的一系列參數

    6、PHCollectionList,表示一組 PHCollection,它本身也是一個 PHCollection,因此 PHCollection 作爲一個集合,可以包含其他集合,這使到

 PhotoKit 的組成比 ALAssetLibrary 要複雜一些。另外與 ALAssetLibrary 相似,一個 PHAsset 可以同時屬於多個不同的 PHAssetCollection,最常見的

photoKit獲取所有照片

- (NSMutableArray *)getAllPhoto{
    NSMutableArray *arr = [NSMutableArray array];
        // 所有智能相冊
    PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (NSInteger i = 0; i < smartAlbums.count; i++) {
        PHCollection *collection = smartAlbums[i];
        //遍歷獲取相冊
        if ([collection isKindOfClass:[PHAssetCollection class]]) {
            PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
            PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
            PHAsset *asset = nil;
            if (fetchResult.count != 0) {
                for (NSInteger j = 0; j < fetchResult.count; j++) {
                    //從相冊中取出照片
                    asset = fetchResult[j];
                    PHImageRequestOptions *opt = [[PHImageRequestOptions alloc]init];
                    opt.synchronous = YES;
                    PHImageManager *imageManager = [[PHImageManager alloc] init];
                    [imageManager requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:opt resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                        if (result) {
                            [arr addObject:result];
                        }
                    }];
        }
            }
    }
        }
    
    //返回所有照片
    return arr;
}

由於此方法爲同步方法 所以需要放在子線程中去執行 例如:

dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSMutableArray *arr = [self getAllPhoto];
        NSLog(@"完成%@ \n照片總數%ld", arr, arr.count);
    });​

我是用AssetsLibrary實現的,這裏就簡單介紹一下實現的步驟,首先添加照片,肯定是用CollectionView來實現的,聲明一個數組存放選中的照片,當個照片數量爲0是,返回一個cell,添加的點擊時間訪問圖庫,否則,返回cell的個數爲照片數量加1,設置cell的樣式,當cell的index小於等於照片數量,點擊可以放大圖片,點擊紅色按鈕可以刪除照片,否則的話添加照片,並且改變collectionView的frame






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章