1. 程式人生 > >iOS-儲存圖片到(自定義)相簿步驟

iOS-儲存圖片到(自定義)相簿步驟

儲存到相簿步驟:

1.儲存圖片到【相機膠捲】

2.擁有一個【自定義相簿】

3.將剛才儲存到【相機膠捲中的圖片】引用到【自定義相簿】

 

儲存圖片到【相機膠捲】

/*
 一、儲存圖片到【自定義相簿】
 1.儲存圖片到【相機膠捲】
 1> C語言函式UIImageWriteToSavedPhotosAlbum
 2> AssetsLibrary框架
 3> Photos框架
 
 2.擁有一個【自定義相簿】
 1> AssetsLibrary框架
 2> Photos框架
 
 3.新增剛才儲存的圖片到【自定義相簿】
 1> AssetsLibrary框架
 2> Photos框架
 
*/ - (IBAction)save:(UIButton *)sender { /* 儲存到相簿步驟: 1.儲存圖片到【相機膠捲】 2.擁有一個【自定義相簿】 3.將剛才儲存到【相機膠捲中的圖片】引用到【自定義相簿】 */ UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil); } - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void
*)contextInfo { if (error) { [SVProgressHUD showErrorWithStatus:@"儲存失敗!"]; } else { [SVProgressHUD showSuccessWithStatus:@"儲存成功!"]; } }
/*
//補充
 錯誤資訊:-[NSInvocation setArgument:atIndex:]: index (2) out of bounds [-1, 1]
 錯誤解釋:引數越界錯誤,方法的引數個數和實際傳遞的引數個數不一致
 */

Photos框架詳解和儲存圖片

1.Photos框架詳解

/*
二、Photos框架須知
 1.PHAsset : 一個PHAsset物件就代表相簿中的一張圖片或者一個視訊
 1> 查 : [PHAsset fetchAssets...]
 2> 增刪改 : PHAssetChangeRequest(包括圖片\視訊相關的所有改動操作)
 
 2.PHAssetCollection : 一個PHAssetCollection物件就代表一個相簿
 1> 查 : [PHAssetCollection fetchAssetCollections...]
 2> 增刪改 : PHAssetCollectionChangeRequest(包括相簿相關的所有改動操作)
 
 3.對相片\相簿的任何【增刪改】操作,都必須放到以下方法的block中執行
 -[PHPhotoLibrary performChanges:completionHandler:]
 -[PHPhotoLibrary performChangesAndWait:error:]
 */

/*
 Foundation和Core Foundation的資料型別可以互相轉換,比如NSString *和CFStringRef
 NSString *string = (__bridge NSString *)kCFBundleNameKey;
 CFStringRef string = (__bridge CFStringRef)@"test";
 
 獲得相機膠捲相簿
 [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil]
 */

/*
 錯誤資訊:This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]
 
// 非同步執行修改操作 [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } completionHandler:^(BOOL success, NSError * _Nullable error) { if (error) { [SVProgressHUD showErrorWithStatus:@"儲存失敗!"]; } else { [SVProgressHUD showSuccessWithStatus:@"儲存成功!"]; } }]; // 同步執行修改操作 NSError *error = nil; [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; } error:&error]; if (error) { [SVProgressHUD showErrorWithStatus:@"儲存失敗!"]; } else { [SVProgressHUD showSuccessWithStatus:@"儲存成功!"]; }
*/

2.Photos框架儲存圖片到相機膠捲

- (IBAction)save:(UIButton *)sender {
    /*
     儲存到相簿步驟:
     1.儲存圖片到【相機膠捲】
     2.擁有一個【自定義相簿】
     3.將剛才儲存到【相機膠捲中的圖片】引用到【自定義相簿】
     */
    NSError *error = nil;

    // 儲存圖片到【相機膠捲】
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image];
    } error:&error];

    if (error) {
        [SVProgressHUD showErrorWithStatus:@"儲存失敗!"];
    } else {
        [SVProgressHUD showSuccessWithStatus:@"儲存成功!"];
    }
}

 

②擁有一個【自定義相簿】

 Foundation和Core Foundation的資料型別可以互相轉換,比如NSString *和CFStringRef

 NSString *string = (__bridge NSString *)kCFBundleNameKey;

 CFStringRef string = (__bridge CFStringRef)@"test";

1.建立一個【自定義相簿】

/** 當前App對應的自定義相簿 */
- (PHAssetCollection *)createdCollection;

- (IBAction)save:(UIButton *)sender {
    /*
     儲存到相簿步驟:
     1.儲存圖片到【相機膠捲】
     2.擁有一個【自定義相簿】
     3.將剛才儲存到【相機膠捲中的圖片】引用到【自定義相簿】
     */
    [self createdCollection];
}

#pragma mark - 獲得當前App對應的自定義相簿
- (PHAssetCollection *)createdCollection
{
    // 獲得軟體名字
    NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleNameKey];
    
    // 抓取所有的自定義相簿
    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    
    // 查詢當前App對應的自定義相簿
    for (PHAssetCollection *collection in collections) {
        if ([collection.localizedTitle isEqualToString:title]) {
            return collection;
        }
    }
    
    /** 當前App對應的自定義相簿沒有被建立過 **/
    // 建立一個【自定義相簿】
    NSError *error = nil;
    __block NSString *createdCollectionID = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
createdCollectionID
= [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier; } error:&error]; if (error) { [SVProgressHUD showErrorWithStatus:@"建立相簿失敗!"]; return nil; } // 根據唯一標識獲得剛才建立的相簿 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject; } /* Foundation和Core Foundation的資料型別可以互相轉換,比如NSString *和CFStringRef NSString *string = (__bridge NSString *)kCFBundleNameKey; CFStringRef string = (__bridge CFStringRef)@"test"; 獲得相機膠捲相簿 [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil] */

2.獲取相簿

#pragma mark - 獲得當前App對應的自定義相簿
// 根據唯一標識獲得剛才建立的相簿
 return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject;

3.儲存圖片到自定義相簿

/** 當前App對應的自定義相簿 */
- (PHAssetCollection *)createdCollection;
/** 返回剛才儲存到【相機膠捲】的圖片 */
- (PHFetchResult<PHAsset *> *)createdAssets;

- (IBAction)save:(UIButton *)sender {
    PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus];
    
    // 請求\檢查訪問許可權 :
    // 如果使用者還沒有做出選擇,會自動彈框,使用者對彈框做出選擇後,才會呼叫block
    // 如果之前已經做過選擇,會直接執行block
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (status == PHAuthorizationStatusDenied) { // 使用者拒絕當前App訪問相簿
                if (oldStatus != PHAuthorizationStatusNotDetermined) {
                    HKLog(@"提醒使用者開啟開關")
                }
            } else if (status == PHAuthorizationStatusAuthorized) { // 使用者允許當前App訪問相簿
                [self saveImageIntoAlbum];
            } else if (status == PHAuthorizationStatusRestricted) { // 無法訪問相簿
                [SVProgressHUD showErrorWithStatus:@"因系統原因,無法訪問相簿!"];
            }
        });
    }];
}

/**
 *  儲存圖片到相簿
 */
- (void)saveImageIntoAlbum
{
    // 獲得相片
    PHFetchResult<PHAsset *> *createdAssets = self.createdAssets;
    if (createdAssets == nil) {
        [SVProgressHUD showErrorWithStatus:@"儲存圖片失敗!"];
        return;
    }
    
    // 獲得相簿
    PHAssetCollection *createdCollection = self.createdCollection;
    if (createdCollection == nil) {
        [SVProgressHUD showErrorWithStatus:@"建立或者獲取相簿失敗!"];
        return;
    }
    
    // 新增剛才儲存的圖片到【自定義相簿】
    NSError *error = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection];
        [request insertAssets:createdAssets atIndexes:[NSIndexSet indexSetWithIndex:0]];
    } error:&error];
    
    // 最後的判斷
    if (error) {
        [SVProgressHUD showErrorWithStatus:@"儲存圖片失敗!"];
    } else {
        [SVProgressHUD showSuccessWithStatus:@"儲存圖片成功!"];
    }
}


#pragma mark - 獲得當前App對應的自定義相簿
- (PHAssetCollection *)createdCollection
{
    // 獲得軟體名字
    NSString *title = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    
    // 抓取所有的自定義相簿
    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    
    // 查詢當前App對應的自定義相簿
    for (PHAssetCollection *collection in collections) {
        if ([collection.localizedTitle isEqualToString:title]) {
            return collection;
        }
    }
    
    /** 當前App對應的自定義相簿沒有被建立過 **/
    // 建立一個【自定義相簿】
    NSError *error = nil;
    __block NSString *createdCollectionID = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        createdCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;
    } error:&error];
    
    if (error) return nil;
    
    // 根據唯一標識獲得剛才建立的相簿
    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionID] options:nil].firstObject;
}

- (PHFetchResult<PHAsset *> *)createdAssets
{
    NSError *error = nil;
    __block NSString *assetID = nil;
    
    // 儲存圖片到【相機膠捲】
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        assetID = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;
    } error:&error];
    
    if (error) return nil;
    
    // 獲取剛才儲存的相片
    return [PHAsset fetchAssetsWithLocalIdentifiers:@[assetID] options:nil];
}

//補充:不帶許可權判斷
//- (IBAction)save {
//    NSError *error = nil;
//
//    // 儲存圖片到【相機膠捲】
//    __block PHObjectPlaceholder *placeholder = nil;
//    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
//        placeholder = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset;
//    } error:&error];
//    if (error) {
//        [SVProgressHUD showErrorWithStatus:@"儲存圖片失敗!"];
//        return;
//    }
//
//    // 獲得相簿
//    PHAssetCollection *createdCollection = self.createdCollection;
//    if (createdCollection == nil) {
//        [SVProgressHUD showErrorWithStatus:@"建立相簿失敗!"];
//        return;
//    }
//
//    // 新增剛才儲存的圖片到【自定義相簿】
//    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
//        PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection];
//        [request insertAssets:@[placeholder] atIndexes:[NSIndexSet indexSetWithIndex:0]];
//    } error:&error];
//
//    // 最後的判斷
//    if (error) {
//        [SVProgressHUD showErrorWithStatus:@"儲存圖片失敗!"];
//    } else {
//        [SVProgressHUD showSuccessWithStatus:@"儲存圖片成功!"];
//    }
//}