iOS保存圖片到相冊

在APP中點擊照片,都會顯示出大圖,然后在大圖的上面會有個保存照片的按鈕,照片直接保存到了系統(tǒng)的【相機膠卷】相冊中,但是因為公司產(chǎn)品的需要,我們需要創(chuàng)建和APP同名的相冊保存在【自定義相冊】里面,這也就是分應(yīng)用存儲,因為用戶可能從QQ,微信,微博分別存儲,下次用戶想找某個應(yīng)用的圖片,直接點開該應(yīng)用相冊即可,提高用戶體驗。
注意:
【自定義相冊】里面的圖片來源于【相機膠卷】相冊中,即:【相機膠卷】引用【自定義相冊】, 如果用戶刪掉【相機膠卷】里面的圖片, 那么【自定義相冊】重的圖片也會刪掉。但是,如果用戶刪掉【自定義相冊】里面的圖片, 那么【相機膠卷】中依然有該圖片。

開發(fā)步驟:
  • 1.先保存圖片到【相機膠卷】(不能直接保存到自定義相冊中)
  • 2.擁有一個【自定義相冊】
  • 3.將剛才保存到【相機膠卷】里面的圖片引用到【自定義相冊】

方法1:用C語言函數(shù)實現(xiàn)

將圖片保存到系統(tǒng)的相冊中,只需要下面兩句代碼就搞定了

//參數(shù)1:圖片對象
//參數(shù)2:成功方法綁定的target
//參數(shù)3:成功后調(diào)用方法
//參數(shù)4:需要傳遞信息(成功后調(diào)用方法的參數(shù))
UIImageWriteToSavedPhotosAlbum(self.imageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
#pragma mark -- <保存到相冊>
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NSString *msg = nil ;
    if(error){
        msg = @"保存圖片失敗" ;
    }else{
        msg = @"保存圖片成功" ;
    }
}

注意:UIImageWriteToSavedPhotosAlbum方法必須實現(xiàn)圖1的代理方法,否則會崩潰。

1.png

界面效果如下:界面圖


效果圖.png
方法2:使用Photos框架實現(xiàn)
2.1 Photos01-基本認識

PHAsset : 一個PHAsset對象就代表相冊中的一張圖片或者一個視頻
PHAssetCollection : 一個PHAssetCollection 對象就代表一個相冊

如果我們想保存圖片到【相機膠卷】,首先要保證添加一個新的PHAsset對象,那么如何操作這些對象呢?無非是對這些對象進行增刪改查。

PHAsset 一個PHAsset對象就代表相冊中的一張圖片或者一個視頻
增刪改 PHAssetChangeRequest 包括圖片/視頻相關(guān)的改動操作

[PHAsset fetchAssets...];

PHAssetCollection 一個PHAssetCollection 對象就代表一個相冊

增刪改 PHAssetCollectionChangeRequest 包括相冊相關(guān)的所有改動操作

[PHAssetCollection fetchAssetCollectionsContainingAsset:...];

2.2 Photos02-保存圖片到相機膠卷
    //保存圖片到【相機膠卷】
    /// 異步執(zhí)行修改操作
    [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
        [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image];
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@",@"保存失敗");
        } else {
            NSLog(@"%@",@"保存成功");
        }
    }];

效果如圖2 圖3所示


2.png
3.png

Tips:
如果直接使用 [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image]; 則會出現(xiàn)如下的崩潰信息

reason: 'This method can only be called from inside of -[PHPhotoLibrary performChanges:completionHandler:] or -[PHPhotoLibrary performChangesAndWait:error:]'

結(jié)論:凡是涉及增刪改的操作,均需要放在performChanges里面執(zhí)行。

 [[PHPhotoLibrary sharedPhotoLibrary]performChanges:^{
       // 這里執(zhí)行操作
    } completionHandler:^(BOOL success, NSError * _Nullable error) {
    }];
2.3 Photos03-創(chuàng)建新的相冊
    NSError *error = nil;
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
        //獲取app名字
        
        NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString*)kCFBundleNameKey];
        //創(chuàng)建一個【自定義相冊】
        [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
    } error:&error];

效果如圖4:


4.png

Tips:如果我們一直點擊保存圖片按鈕,則會出現(xiàn)重復(fù)創(chuàng)建多個相冊的問題:

如圖5所示

5.png

接著我們來解決這個問題。

2.4 Photos04-查詢相冊
    NSString *title = [NSBundle mainBundle].infoDictionary[(__bridge NSString*)kCFBundleNameKey];
    //查詢所有【自定義相冊】
    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    PHAssetCollection *createCollection = nil;
    for (PHAssetCollection *collection in collections) {
        if ([collection.localizedTitle isEqualToString:title]) {
            createCollection = collection;
            break;
        }
    }
    if (createCollection == nil) {
        //當(dāng)前對應(yīng)的app相冊沒有被創(chuàng)建
        //創(chuàng)建一個【自定義相冊】
        NSError *error = nil;
        [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
            //創(chuàng)建一個【自定義相冊】
            [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title];
        } error:&error];

    }

輸出結(jié)果:
此時,無論你點擊多少次,均只會創(chuàng)建一個與APP同名的相冊。

Tips: 如果我們想把圖片保存到【自定義相冊】里面的話,必須拿到相冊對象,但是細心地你此時可能會發(fā)現(xiàn),如果是第一次創(chuàng)建相冊(即:相冊中沒有與APP同名的相冊),createCollection對象會為nil,所以我們還需要優(yōu)化創(chuàng)建【自定義相冊】的代碼。

核心代碼:

    if (createCollection == nil) {
        //當(dāng)前對應(yīng)的app相冊沒有被創(chuàng)建
        //創(chuàng)建一個【自定義相冊】
        NSError *error = nil;
        __block NSString *createCollectionID = nil;
        [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
            //創(chuàng)建一個【自定義相冊】
           createCollectionID = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;
        } error:&error];
        createCollection = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createCollectionID] options:nil].firstObject;
    }
    NSLog(@"%@",createCollection);

輸出結(jié)果:

2018-08-12 12:31:59.198751+0800 SavePhotoDemo[971:36240] <PHAssetCollection: 0x7fde6dc33960> 7C7FBA58-54AA-4320-9B2A-593BB75428FB/L0/040, title:"SavePhotoDemo", subtitle:"(null)" assetCollectionType=1/2
2.5 Photos05-保存圖片到自定義相冊

我們創(chuàng)建完相冊之后,需要將【相機膠卷】中的圖片放到【自定義相冊】里面去。
核心代碼如下:

    // 1.先保存圖片到【相機膠卷】
    /// 同步執(zhí)行修改操作
    NSError *error = nil;
    __block PHObjectPlaceholder *placeholder = nil;
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
       placeholder =  [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset;
    } error:&error];
    if (error) {
        NSLog(@"保存失敗");
        return;
    }
    // 2.擁有一個【自定義相冊】
    PHAssetCollection * assetCollection = self.createCollection;
    if (assetCollection == nil) {
        NSLog(@"創(chuàng)建相冊失敗");
    }
    // 3.將剛才保存到【相機膠卷】里面的圖片引用到【自定義相冊】
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
        PHAssetCollectionChangeRequest *requtes = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
        [requtes addAssets:@[placeholder]];
    } error:&error];
    if (error) {
        NSLog(@"保存圖片失敗");
    } else {
        NSLog(@"保存圖片成功");
    }

此時,我們點擊保存圖片到新建相冊~按鈕的時候,改圖片變被保存到【相機膠卷】和【自定義相冊】里面了。
如圖6所示

6.png

但是,此時你會發(fā)現(xiàn),每保存新的圖片,自定義相冊中均會添加到后面,那么如何把每次新添加的圖片前置呢?我們發(fā)現(xiàn)【相機膠卷】中每次新的圖片均會作為封面,系統(tǒng)自帶的這個比較智能,如圖圖7所示


7.png

所以修改添加圖片到相冊的代碼

    // 3.將剛才保存到【相機膠卷】里面的圖片引用到【自定義相冊】
    [[PHPhotoLibrary sharedPhotoLibrary]performChangesAndWait:^{
        PHAssetCollectionChangeRequest *requtes = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
        [requtes insertAssets:@[placeholder] atIndexes:[NSIndexSet indexSetWithIndex:0]];
    } error:&error];
    

此時,【自定義相冊】中新添加的圖片便會作為相冊的封面了,效果如圖8所示。

8.png

Demo下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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