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

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

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

方式一:
demo:

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


Snip20160416_8.png
方式二:

保存圖片到相冊指定相冊里,注意:其實只是把Camera Roll的相片又引用到了新的相冊里
因為無論什么圖片,都會首先保存在Camera Roll這個相冊,之后根據(jù)自己的設(shè)置,才會保存
在指定的相冊中

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

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

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

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

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

  • Photos框架須知

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

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

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

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

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

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

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

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

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

獲取相冊中的圖片

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

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

demo1:
  • 點擊屏幕時,就跳轉(zhuǎn)到系統(tǒng)相冊進行選擇圖片(只能選擇一張照片)
@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];
}
//實現(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.獲取多張相冊里的圖片(圖片 >= 2)

用到框架和實現(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è)置相冊的類型:相機膠卷 + 自定義相冊
            picker.assetCollectionSubtypes = @[
              @(PHAssetCollectionSubtypeSmartAlbumUserLibrary),
              @(PHAssetCollectionSubtypeAlbumRegular)];
            // 不需要顯示空的相冊
            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來modal別的控制器,因為此時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)容合作請聯(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)容