iOS之保存圖片到系統(tǒng)相冊(cè)和從系統(tǒng)相冊(cè)選取一張或者多張照片

以下內(nèi)容是如何把APP中的圖片保存到相冊(cè)中和如何在相冊(cè)中選取圖片(一張或多張)

一: 把軟件中的圖片保存到系統(tǒng)相冊(cè)或者保存到自己創(chuàng)建的相冊(cè)中

方式一:
demo:

保存圖片到系統(tǒng)相冊(cè),這只是簡(jiǎn)單的把圖片保存到系統(tǒng)相冊(cè)中,


Snip20160416_8.png
方式二:

保存圖片到相冊(cè)指定相冊(cè)里,注意:其實(shí)只是把Camera Roll的相片又引用到了新的相冊(cè)里
因?yàn)闊o(wú)論什么圖片,都會(huì)首先保存在Camera Roll這個(gè)相冊(cè),之后根據(jù)自己的設(shè)置,才會(huì)保存
在指定的相冊(cè)中

  • 1>思路:
Snip20160416_9.png
  • 2>思路步驟 :

    • 1.添加圖片到【相機(jī)膠卷】
      1>UIImageWriteToSavedPhotosAlbum函數(shù)
      2> AssetsLibrary框架
      3>Photos框架(推薦)

    • 2.擁有一個(gè)【自定義相冊(cè)】
      1> AssetsLibrary框架
      2> Photos框架(推薦)

    • 3.將剛才添加到【相機(jī)膠卷】的圖片,引用(添加)到【自定義相冊(cè)】
      1> AssetsLibrary框架
      2> Photos框架(推薦)

  • 3>需要用到的框架,主要還是用到Photos框架,也是蘋(píng)果自帶的框架

  • Photos框架須知

  • 1.PHAsset : 一個(gè)PHAsset對(duì)象代表一張圖片或者一個(gè)視頻文件
    1> 負(fù)責(zé)查詢一堆的PHAsset對(duì)象

  • 2.PHAssetCollection : 一個(gè)PHAssetCollection對(duì)象代表一個(gè)相冊(cè)
    1> 負(fù)責(zé)查詢一堆的PHAssetCollection對(duì)象

  • 3.PHAssetChangeRequest
    1> 負(fù)責(zé)執(zhí)行對(duì)PHAsset的【增刪改】操作
    2> 這個(gè)類(lèi)只能放在
    -[PHPhotoLibrary performChanges:completionHandler:]或者
    -[PHPhotoLibrary performChangesAndWait:error:]方法的block中使用

  • 4.PHAssetCollectionChangeRequest
    1> 負(fù)責(zé)執(zhí)行對(duì)PHAssetCollection的【增刪改】操作
    2> 這個(gè)類(lèi)只能放在
    -[PHPhotoLibrary performChanges:completionHandler:] 或者
    -[PHPhotoLibrary performChangesAndWait:error:]方法的block中使用

具體代碼實(shí)現(xiàn)步驟:
demo:

導(dǎo)入框架
#import <Photos/Photos.h>
以下總共抽取出來(lái)了三個(gè)方法,方便點(diǎn)擊保存按鈕時(shí)調(diào)用

// 獲得剛才添加到【相機(jī)膠卷】中的圖片 
-(PHFetchResult<PHAsset *> *)createdAssets
{
    __block NSString *createdAssetId = nil;
    // 添加圖片到【相機(jī)膠卷】
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        createdAssetId = [PHAssetChangeRequest creationRequestForAssetFromImage:self.imageView.image].placeholderForCreatedAsset.localIdentifier;
    } error:nil];
    if (createdAssetId == nil) return nil;
    // 在保存完畢后取出圖片
    return [PHAsset fetchAssetsWithLocalIdentifiers:@[createdAssetId] options:nil];
}
獲得【自定義相冊(cè)】
-(PHAssetCollection *)createdCollection
{
    // 獲取軟件的名字作為相冊(cè)的標(biāo)題(如果需求不是要軟件名稱作為相冊(cè)名字就可以自己把這里改成想要的名稱)
    NSString *title = [NSBundle mainBundle].infoDictionary[(NSString *)kCFBundleNameKey];   
    // 獲得所有的自定義相冊(cè)
    PHFetchResult<PHAssetCollection *> *collections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
    for (PHAssetCollection *collection in collections) {
        if ([collection.localizedTitle isEqualToString:title]) {
            return collection;
        }
    }
    // 代碼執(zhí)行到這里,說(shuō)明還沒(méi)有自定義相冊(cè)
    __block NSString *createdCollectionId = nil;
    // 創(chuàng)建一個(gè)新的相冊(cè)
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        createdCollectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier;
    } error:nil];
    if (createdCollectionId == nil) return nil;
    // 創(chuàng)建完畢后再取出相冊(cè)
    return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[createdCollectionId] options:nil].firstObject;
}
//保存圖片到相冊(cè)
-(void)saveImageIntoAlbum
{
    // 獲得相片
    PHFetchResult<PHAsset *> *createdAssets = self.createdAssets;
    // 獲得相冊(cè)
    PHAssetCollection *createdCollection = self.createdCollection;
    if (createdAssets == nil || createdCollection == nil) {
        [SVProgressHUD showErrorWithStatus:@"保存失??!"];
        return;
    }
    // 將相片添加到相冊(cè)
    NSError *error = nil;
    [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
        PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:createdCollection];
        [request insertAssets:createdAssets atIndexes:[NSIndexSet indexSetWithIndex:0]];
    } error:&error];
    // 保存結(jié)果
    if (error) {
        [SVProgressHUD showErrorWithStatus:@"保存失敗!"];
    } else {
        [SVProgressHUD showSuccessWithStatus:@"保存成功!"];
    }
}
//點(diǎn)擊保存按鈕時(shí)調(diào)用
-(IBAction)save {
    // requestAuthorization方法的功能
     1.如果用戶還沒(méi)有做過(guò)選擇,這個(gè)方法就會(huì)彈框讓用戶做出選擇
     1> 用戶做出選擇以后才會(huì)回調(diào)block
     2.如果用戶之前已經(jīng)做過(guò)選擇,這個(gè)方法就不會(huì)再?gòu)椏?,直接回調(diào)block,傳遞現(xiàn)在的授權(quán)狀態(tài)給block
    PHAuthorizationStatus oldStatus = [PHPhotoLibrary authorizationStatus];
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
        dispatch_async(dispatch_get_main_queue(), ^{
            switch (status) {
                case PHAuthorizationStatusAuthorized: {
                    //  保存圖片到相冊(cè)
                    [self saveImageIntoAlbum];
                    break;
                } 
                case PHAuthorizationStatusDenied: {
                    if (oldStatus == PHAuthorizationStatusNotDetermined) return;
                    NSLog(@"提醒用戶打開(kāi)相冊(cè)的訪問(wèn)開(kāi)關(guān)");
                    break;
                }       
                case PHAuthorizationStatusRestricted: {
                    [SVProgressHUD showErrorWithStatus:@"因系統(tǒng)原因,無(wú)法訪問(wèn)相冊(cè)!"];
                    break;
                }       
                default:
                    break;
            }
        });
    }];
  用戶還沒(méi)有對(duì)當(dāng)前App授權(quán)過(guò)(用戶從未點(diǎn)擊過(guò)Don't Allow或者OK按鈕)
  PHAuthorizationStatusRestricted
  因?yàn)橐恍┫到y(tǒng)原因?qū)е聼o(wú)法訪問(wèn)相冊(cè)(比如家長(zhǎng)控制)
  PHAuthorizationStatusDenied
  用戶已經(jīng)明顯拒絕過(guò)當(dāng)前App訪問(wèn)相片數(shù)據(jù)(用戶已經(jīng)點(diǎn)擊過(guò)Don't Allow按鈕)
  PHAuthorizationStatusAuthorized
  用戶已經(jīng)允許過(guò)當(dāng)前App訪問(wèn)相片數(shù)據(jù)(用戶已經(jīng)點(diǎn)擊過(guò)OK按鈕)

二 : 獲取系統(tǒng)的相冊(cè)圖片(一張或者多張)

UIImagePickerControllerSourceTypePhotoLibrary, 從所有相冊(cè)中選擇圖片
UIImagePickerControllerSourceTypeCamera, 利用照相機(jī)拍一張圖片(自定義照相機(jī)AVCaptureSession)
UIImagePickerControllerSourceTypeSavedPhotosAlbum 從Moments相冊(cè)中選擇圖片
1.獲取一張相冊(cè)里的圖片(圖片 == 1)

獲取相冊(cè)中的圖片

  • 1.單張
    1> UIImagePickerController
    2> AssetsLibrary框架
    3> Photos框架

  • 2.多張(>=2張)
    1> AssetsLibrary框架
    2> Photos框架

demo1:
  • 點(diǎn)擊屏幕時(shí),就跳轉(zhuǎn)到系統(tǒng)相冊(cè)進(jìn)行選擇圖片(只能選擇一張照片)
@interface ViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITableViewDelegate>
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UIImagePickerController *picker = [[UIImagePickerController alloc] init];
    picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    picker.delegate = self;
    [self presentViewController:picker animated:YES completion:nil];
}
//實(shí)現(xiàn)代理方法<UIImagePickerControllerDelegate>
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
    // 關(guān)閉選擇圖片界面
    [picker dismissViewControllerAnimated:YES completion:nil];
    // 獲得選擇的圖片
    UIImageView *imageView = [[UIImageView alloc] init];
    imageView.image = info[UIImagePickerControllerOriginalImage];
    imageView.frame = CGRectMake(0, 0, 100, 100);
    [self.view addSubview:imageView];
}
-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    // .....
    // 關(guān)閉選擇圖片界面
    [picker dismissViewControllerAnimated:YES completion:nil];
}
2.獲取多張相冊(cè)里的圖片(圖片 >= 2)

用到框架和實(shí)現(xiàn)協(xié)議一些方法

demo2(部分重要代碼):
#import "ViewController.h"
#import <Photos/Photos.h>
#import <CTAssetsPickerController/CTAssetsPickerController.h>
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status){
        if (status != PHAuthorizationStatusAuthorized) return;     
        dispatch_async(dispatch_get_main_queue(), ^{
            CTAssetsPickerController *picker = [[CTAssetsPickerController alloc] init];
            picker.delegate = self;
            // 顯示選擇的索引
            picker.showsSelectionIndex = YES;
            // 設(shè)置相冊(cè)的類(lèi)型:相機(jī)膠卷 + 自定義相冊(cè)
            picker.assetCollectionSubtypes = @[
              @(PHAssetCollectionSubtypeSmartAlbumUserLibrary),
              @(PHAssetCollectionSubtypeAlbumRegular)];
            // 不需要顯示空的相冊(cè)
            picker.showsEmptyAlbums = NO;
            [self presentViewController:picker animated:YES completion:nil];
        });
    }];
}
#pragma mark - <CTAssetsPickerControllerDelegate>
-(BOOL)assetsPickerController:(CTAssetsPickerController *)picker shouldSelectAsset:(PHAsset *)asset
{
    NSInteger max = 2;  
    if (picker.selectedAssets.count >= max) {
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:[NSString stringWithFormat:@"最多選擇%zd張圖片", max] preferredStyle:UIAlertControllerStyleAlert];
        [alert addAction:[UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]];
        [picker presentViewController:alert animated:YES completion:nil];
        // 這里不能使用self來(lái)modal別的控制器,因?yàn)榇藭r(shí)self.view不在window上
        return NO;
    }
    return YES;
}
-(void)assetsPickerController:(CTAssetsPickerController *)picker didFinishPickingAssets:(NSArray *)assets
{
    // 關(guān)閉圖片選擇界面
    [picker dismissViewControllerAnimated:YES completion:nil];
    // 基本配置
    CGFloat scale = [UIScreen mainScreen].scale;
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.resizeMode   = PHImageRequestOptionsResizeModeExact;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    // 遍歷選擇的所有圖片
    for (NSInteger i = 0; i < assets.count; i++) {
        PHAsset *asset = assets[i];
        CGSize size = CGSizeMake(asset.pixelWidth / scale, asset.pixelHeight / scale);
        // 獲取圖片
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            UIImageView *imageView = [[UIImageView alloc] init];
            imageView.image = result;
            imageView.frame = CGRectMake((i % 3) * 110, (i / 3) * 110, 100, 100);
            [self.view addSubview:imageView];
        }];
    }
}
效果:
Snip20160419_13.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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