iOS - Photos框架詳解(調(diào)用系統(tǒng)相冊)

人一切的痛苦,本質(zhì)上都是對自己的無能的憤怒。


1.相冊訪問權限
2.相冊中圖片變化的監(jiān)聽
3.讀取相冊中的圖片
4.將圖片保存到相冊

相冊訪問權限

使用系統(tǒng)相冊的時候,首先判斷是否有權限,沒有權限的話,可以彈出提示框。

PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];  
if (status == PHAuthorizationStatusRestricted ||  
    status == PHAuthorizationStatusDenied) {  
    // 這里便是無訪問權限  
    //可以彈出個提示框,叫用戶去設置打開相冊權限
}  else {
    //這里就是用權限
}

相冊中圖片變化的監(jiān)聽

相冊監(jiān)聽中的回調(diào)方法是在 子線程 中的,因此要改變UI布局的話,必須回到主線程

[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];    //創(chuàng)建監(jiān)聽者
[[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];    //移除監(jiān)聽者

//相冊變化回調(diào)  
- (void)photoLibraryDidChange:(PHChange *)changeInstance  
{  

    dispatch_sync(dispatch_get_main_queue(), ^{  
        //修改UI
    });  

}  

獲取相冊中的圖片

** 幾個常用的類 **
**PHAsset **: 代表照片庫中的一個資源,跟 ALAsset 類似,通過 PHAsset 可以獲取和保存資源。每個PHAsset就是一張圖片的詳細信息,包括圖片、位置、時間等。

** PHFetchOptions **: 獲取資源時的參數(shù),可以傳 nil,即使用系統(tǒng)默認值。

** PHFetchResult **: 表示一系列的資源集合,也可以是相冊的集合。

** PHAssetCollection **: 表示一個相冊或者一個時刻,或者是一個智能相冊(系統(tǒng)提供的特定的一系列相冊,例如:最近刪除,視頻列表,收藏等等)。

** PHImageManager **: 用于處理資源的加載,加載圖片的過程帶有緩存處理,可以通過傳入一個 PHImageRequestOptions 控制資源的輸出尺寸等規(guī)格。

** PHImageRequestOptions **: 如上面所說,控制加載圖片時的一系列參數(shù)。

// 獲取所有資源的集合,并按資源的創(chuàng)建時間排序
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

//獲取相機膠卷所有圖片
PHFetchResult *assets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];

PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];

//設置顯示模式
/*
PHImageRequestOptionsResizeModeNone    //選了這個就不會管傳如的size了 ,要自己控制圖片的大小,建議還是選Fast
PHImageRequestOptionsResizeModeFast    //根據(jù)傳入的size,迅速加載大小相匹配(略大于或略小于)的圖像 
PHImageRequestOptionsResizeModeExact    //精確的加載與傳入size相匹配的圖像 
*/
option.resizeMode = PHImageRequestOptionsResizeModeFast;
option.synchronous = NO;
option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;

CGFloat scale = [UIScreen mainScreen].scale;
CGSize screenSize = [UIScreen mainScreen].bounds.size;

typeof(self)weakSelf = self;
for (PHAsset *asset in assets) {
    
    [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(screenSize.width*scale, screenSize.height*scale) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        //我這里用個模型接儲存了圖片的 localIdentifier 和圖片本身
        //還有很多信息,根據(jù)自己的需求來取
        CellModel * model = [CellModel new];
        model.localIdentifier = asset.localIdentifier;
        model.image = [UIImage imageWithData:UIImageJPEGRepresentation(result, 0.5)];
        
        [weakSelf.cellImageArray addObject:model];
        
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf reloadData];
        });
        
    }];
    
}

將圖片保存到相冊

  • 方法一:
    • 優(yōu)點:簡單快捷
    • 缺點:無法直接保存到自定義相冊
- (IBAction)savePhoto {
    //  - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
    //只能保存到相機膠卷(不能保存到自定義相冊)
    UIImageWriteToSavedPhotosAlbum(self.Photo.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}

//回調(diào)判斷保存是否成功
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        //保存失敗
    }else{
        //保存成功
    }
}
  • ** 方法二: **
    • 優(yōu)點:能夠保存到任何相冊
    • 缺點:沒有第一種方法簡單
 // 添加圖片到自己相冊
 - (void)savePhoto
 {
     [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
         // 1.創(chuàng)建圖片請求類(創(chuàng)建系統(tǒng)相冊中新的圖片)PHAssetCreationRequest
         // 把圖片放在系統(tǒng)相冊
         PHAssetCreationRequest *assetCreationRequest = [PHAssetCreationRequest creationRequestForAssetFromImage:_imageView.image];
        
         // 2.創(chuàng)建相冊請求類(修改相冊)PHAssetCollectionChangeRequest
         PHAssetCollectionChangeRequest *assetCollectionChangeRequest = nil;
        
         // 獲取之前相冊
         PHAssetCollection *assetCollection = [self fetchAssetCollection:@"百思不得姐"];
        
         // 判斷是否已有相冊
         if (assetCollection) {
             // 如果存在已有同名相冊   指定這個相冊,創(chuàng)建相冊請求修改類  
             assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
         } else {  //不存在,創(chuàng)建新的相冊
             assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"百思不得姐"];
         } 
         // 3.把圖片添加到相冊中
         // NSFastEnumeration:以后只要看到這個,就可以表示數(shù)組
         //assetCreationRequest.placeholderForCreatedAsset 圖片請求類占位符(相當于一個內(nèi)存地址) 
          //因為creationRequestForAssetFromImage方法是異步實行的,在這里不能保證 assetCreationRequest有值
  
         [assetCollectionChangeRequest addAssets:@[assetCreationRequest.placeholderForCreatedAsset]];
  
     } completionHandler:^(BOOL success, NSError * _Nullable error) {
        
         if (success) {
             [SVProgressHUD showSuccessWithStatus:@"保存成功"];
         } else {
             [SVProgressHUD showErrorWithStatus:@"保存失敗"];
         }
        
     }];
 }
 
 // 指定相冊名稱,獲取相冊
 - (PHAssetCollection *)fetchAssetCollection:(NSString *)title
 {
     // 獲取相簿中所有自定義相冊
     PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
     遍歷相冊,判斷是否存在同名的相冊
     for (PHAssetCollection *assetCollection in result) {
         if ([title isEqualToString:assetCollection.localizedTitle]) {  存在,就返回這個相冊
             return assetCollection;
         }
     }  
     return nil;
 }
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容