工作之余,研究了一下相機與相冊的自定義,在這里整理成篇僅供參考學習,希望可以給大家帶來些許幫助,也期待大家的批評指正。
自定義相冊
GIF 示例:
DEMO下載地址:https://github.com/IMCCP/CCPCustomCamera
在 iOS 設備中,照片是相當重要的一部分。在 iOS8.0之前,開發者只能使用 AssetsLibrary 框架來訪問設備的照片庫。而在 iOS8 之后,蘋果提供了一個名為 PhotoKit 的框架,一個可以讓應用更好地與設備照片庫對接的框架.由于市面上有一部分應用還支持iOS7,同時為了更加全面的學習,在這里將整理AssetsLibrary 框架與 PhotoKit 框架的相關知識,供大家參考學習.
一、AssetsLibrary 基本介紹
AssetsLibrary: 代表整個設備中的資源庫(照片庫),通過 AssetsLibrary 可以獲取和包括設備中的照片和視頻
ALAssetsGroup: 映射照片庫中的一個相冊,通過 ALAssetsGroup 可以獲取某個相冊的信息,相冊下的資源,同時也可以對某個相冊添加資源。
ALAsset: 映射照片庫中的一個照片或視頻,通過 ALAsset 可以獲取某個照片或視頻的詳細信息,或者保存照片和視頻。
ALAssetRepresentation: ALAssetRepresentation 是對 ALAsset 的封裝(但不是其子類),可以更方便地獲取 ALAsset 中的資源信息,每個 ALAsset 都有至少有一個 ALAssetRepresentation 對象,可以通過 defaultRepresentation 獲取。
二、PhotoKit 基本介紹
PhotoKit 是一套比 AssetsLibrary 更完整也更高效的庫,對資源的處理跟 AssetsLibrary 也有很大的不同。
PhotoKit 基本構成的介紹:
PHAsset: 代表照片庫中的一個資源,跟 ALAsset 類似,通過 PHAsset 可以獲取和保存資源
PHFetchOptions: 獲取資源時的參數,可以傳 nil,即使用系統默認值
PHAssetCollection: PHCollection 的子類,表示一個相冊或者一個時刻,或者是一個「智能相冊(系統提供的特定的一系列相冊,例如:最近刪除,視頻列表,收藏等等,如下圖所示)
PHFetchResult: 表示一系列的資源結果集合,也可以是相冊的集合,從PHCollection 的類方法中獲得
PHImageManager: 用于處理資源的加載,加載圖片的過程帶有緩存處理,可以通過傳入一個 PHImageRequestOptions 控制資源的輸出尺寸等規格
PHImageRequestOptions: 如上面所說,控制加載圖片時的一系列參數
三、主要功能
1.獲取相冊圖片資源;
2.自定義相冊功能;
3.圖片瀏覽器功能;
4.主要 工具類 介紹:
a.CCPPhotoAlbumViewController 控制器 主要要來進行相冊資源的讀?。?/p>
- (void)viewDidLoad {
[super viewDidLoad];
[self makeUI];
//進行系統型號的判斷,調用不同的圖庫處理框架
if ([self iOSIsbefore_iOS8]) {
[self iOSBefore_iOS8];
} else {
[self iOSAfter_iOS8];
}
}
//系統版本小于8.0
- (void) iOSBefore_iOS8 {
//提示
NSString *tipTitle = nil;
//相冊的訪問狀態
ALAuthorizationStatus authorizationStatus = [ALAssetsLibrary authorizationStatus];
/* 獲取當前應用對照片的訪問授權狀態
ALAuthorizationStatusNotDetermined = 0, // 用戶還沒有做出選擇這個應用程序的問候
ALAuthorizationStatusRestricted, // 這個應用程序沒有被授權訪問照片數據。當前用戶不能改變應用程序的狀態,是受限制的。如家長控制權限
ALAuthorizationStatusDenied, // 用戶已拒絕該應用程序訪問照片數據
ALAuthorizationStatusAuthorized // 用戶已授權該應用可以訪問
*/
// 如果沒有獲取訪問授權,或者訪問授權狀態已經被明確禁止,則顯示提示語,引導用戶開啟授權
if (authorizationStatus == ALAuthorizationStatusRestricted || authorizationStatus == ALAuthorizationStatusDenied) {
NSDictionary *mainInfoDictionary = [[NSBundle mainBundle] infoDictionary];
NSString *myAppName = [mainInfoDictionary objectForKey:@"CFBundleDisplayName"];
tipTitle = [NSString stringWithFormat:@"請在設備的\"設置-隱私-照片\"選項中,允許%@訪問你的手機相冊", myAppName];
} else {
[self.assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (group) {
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
if (group.numberOfAssets > 0) {
// 把相冊儲存到數組中,方便后面展示相冊時使用
[self.assetsArray addObject:group];
[self.nameArray addObject:[group valueForProperty:ALAssetsGroupPropertyName]];
//獲取相冊封面圖
UIImage *posterImage = [UIImage imageWithCGImage:[group posterImage]];
[self.posterImageArray addObject:posterImage];
}
} else {
if ([self.assetsArray count] > 0) {
// 把所有的相冊儲存完畢,可以展示相冊列表
} else {
// 沒有任何有資源的相冊,輸出提示
}
}
} failureBlock:^(NSError *error) {
NSLog(@"Asset group not found!\n");
}];
dispatch_async(dispatch_get_main_queue(), ^{
[self.showTableView reloadData];
});
}
}
//系統版本號大于等于8.0
- (void) iOSAfter_iOS8 {
/*
PHAssetCollectionTypeAlbum 自建相冊
PHAssetCollectionTypeSmartAlbum 智能相冊
PHAssetCollectionTypeMoment 時刻相冊
智能相冊子類型
PHAssetCollectionSubtypeSmartAlbumGeneric 通用的
PHAssetCollectionSubtypeSmartAlbumPanoramas 全景
PHAssetCollectionSubtypeSmartAlbumVideos 視屏
PHAssetCollectionSubtypeSmartAlbumFavorites 收藏
PHAssetCollectionSubtypeSmartAlbumTimelapses 延時視屏,也會在PHAssetCollectionSubtypeSmartAlbumVideos在出現
PHAssetCollectionSubtypeSmartAlbumAllHidden 隱藏的
PHAssetCollectionSubtypeSmartAlbumRecentlyAdded 最近添加
PHAssetCollectionSubtypeSmartAlbumBursts 連拍
PHAssetCollectionSubtypeSmartAlbumSlomoVideos Slomo是slow motion的縮寫,高速攝影慢動作解析
PHAssetCollectionSubtypeSmartAlbumUserLibrary 用戶所有的資源
PHAssetCollectionSubtypeSmartAlbumSelfPortraits 所有前置攝像頭拍的照片和視屏
PHAssetCollectionSubtypeSmartAlbumScreenshots 所有的截屏圖
*/
//權限
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusDenied || status == PHAuthorizationStatusRestricted) {
[self noticeAlerPhotos];
}else{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
PHFetchOptions *option = [[PHFetchOptions alloc] init];
//排序方式
option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"modificationDate" ascending:NO]];
// 列出所有相冊智能相冊
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
for (NSInteger i = 0; i < smartAlbums.count; i++) {
// 獲取一個相冊(PHAssetCollection)
PHCollection *collection = smartAlbums[i];
if ([collection isKindOfClass:[PHAssetCollection class]]) {
PHAssetCollection *assetCollection = (PHAssetCollection *)collection;
// 從每一個智能相冊中獲取到的 PHFetchResult 中包含的才是真正的資源(PHAsset)
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
if (fetchResult.count > 0) {
[self.assetsArray addObject:fetchResult];
[self.nameArray addObject:assetCollection.localizedTitle];
//獲取封面圖片,就是第一張圖片
PHAsset *asset = (PHAsset *)fetchResult.firstObject;
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
//默認的是異步加載,這里選擇了同步
options.synchronous = YES;
//PHImageManagerMaximumSize:獲取原圖,占用很大內存 建議不要使用
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFill options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info)
{
[self.posterImageArray addObject:result];
}];
}
}else {
NSAssert(NO, @"Fetch collection not PHCollection: %@", collection);
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.showTableView reloadData];
});
}
}
}];
}
// 獲取所有資源的集合,并按資源的創建時間排序
// PHFetchOptions *options = [[PHFetchOptions alloc] init];
// options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
// PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];
//
// // 這時 assetsFetchResults 中包含的,應該就是各個資源(PHAsset)
// for (NSInteger i = 0; i < assetsFetchResults.count; i++) {
// // 獲取一個資源(PHAsset)
// PHAsset *asset = assetsFetchResults[i];
// }
//
// NSLog(@"%@",assetsFetchResults);
}
b.CCPShowPhotoVC 控制器 主要用于獲取到的對應照片的展示
如圖:
c.XLPhotoBrowser 主要用于圖片的瀏覽
本著不重復造輪子的原則,demo中圖片瀏覽器使用了 XLPhotoBrowser
XLPhotoBrowser下載地址:https://github.com/Shannoon/XLPhotoBrowser
在這里對框架作者表示感謝!
四、參考:
a.http://kayosite.com/ios-development-and-detail-of-photo-framework.html
b.[http://www.lxweimin.com/p/535bfe3c328f](http://www.lxweimin.com/p/535bfe3c3
c.http://www.lxweimin.com/p/cc85282fac5e
d. http://www.cnblogs.com/Jenaral/p/5580497.html
在這里對blog作者表示感謝!
由于篇幅有限,在這里不再詳細的展開,demo中對一些坑點都做了詳細的注釋,如果您有需要可下載demo進行查看.
感謝您的閱讀,期待您的 Star,如果在使用中您有任何問題,可以在 github issue,我會盡自己能力給您答復 。