以下內容是如何把APP中的圖片保存到相冊中和如何在相冊中選取圖片(一張或多張)
一: 把軟件中的圖片保存到系統相冊或者保存到自己創建的相冊中
方式一:
demo:
保存圖片到系統相冊,這只是簡單的把圖片保存到系統相冊中
傳入博客的參考圖片加載不出來,請參考OnlyChenJ的簡書

方式二:
保存圖片到相冊指定相冊里,注意:其實只是把Camera Roll
的相片又引用到了新的相冊里
因為無論什么圖片,都會首先保存在Camera Roll
這個相冊,之后根據自己的設置,才會保存
在指定的相冊中
- 1>思路:

-
2>思路步驟 :
-
1.添加圖片到【相機膠卷】
1>UIImageWriteToSavedPhotosAlbum
函數
2>AssetsLibrary
框架
3>Photos
框架(推薦) -
2.擁有一個【自定義相冊】
1>AssetsLibrary
框架
2>Photos
框架(推薦) -
3.將剛才添加到【相機膠卷】的圖片,引用(添加)到【自定義相冊】
1>AssetsLibrary
框架
2>Photos
框架(推薦)
-
-
3>需要用到的框架,主要還是用到
Photos
框架,也是蘋果自帶的框架-
Photos框架須知
-
1.PHAsset : 一個
PHAsset
對象代表一張圖片或者一個視頻文件
1> 負責查詢一堆的PHAsset
對象 -
2.
PHAssetCollection :
一個PHAssetCollection
對象代表一個相冊
1> 負責查詢一堆的PHAssetCollection
對象 -
3.
PHAssetChangeRequest
1> 負責執行對PHAsset
的【增刪改】操作
2> 這個類只能放在-[PHPhotoLibrary performChanges:completionHandler:]
或者-[PHPhotoLibrary performChangesAndWait:error:]
方法的block
中使用 -
4.
PHAssetCollectionChangeRequest
1> 負責執行對PHAssetCollection
的【增刪改】操作
2> 這個類只能放在-[PHPhotoLibrary performChanges:completionHandler:]
或者-[PHPhotoLibrary performChangesAndWait:error:]
方法的block
中使用具體代碼實現步驟:
demo:
導入框架
#import <Photos/Photos.h>
以下總共抽取出來了三個方法,方便點擊保存按鈕時調用// 獲得剛才添加到【相機膠卷】中的圖片 -(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 { // 獲取軟件的名字作為相冊的標題(如果需求不是要軟件名稱作為相冊名字就可以自己把這里改成想要的名稱) 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; } } // 代碼執行到這里,說明還沒有自定義相冊 __block NSString *createdCollectionId = nil; // 創建一個新的相冊 [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ createdCollectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title].placeholderForCreatedAssetCollection.localIdentifier; } error:nil]; if (createdCollectionId == nil) return nil; // 創建完畢后再取出相冊 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]; // 保存結果 if (error) { [SVProgressHUD showErrorWithStatus:@"保存失敗!"]; } else { [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } } //點擊保存按鈕時調用 -(IBAction)save { // requestAuthorization方法的功能 1.如果用戶還沒有做過選擇,這個方法就會彈框讓用戶做出選擇 1> 用戶做出選擇以后才會回調block 2.如果用戶之前已經做過選擇,這個方法就不會再彈框,直接回調block,傳遞現在的授權狀態給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(@"提醒用戶打開相冊的訪問開關"); break; } case PHAuthorizationStatusRestricted: { [SVProgressHUD showErrorWithStatus:@"因系統原因,無法訪問相冊!"]; break; } default: break; } }); }];
用戶還沒有對當前App授權過(用戶從未點擊過Don't Allow或者OK按鈕) PHAuthorizationStatusRestricted 因為一些系統原因導致無法訪問相冊(比如家長控制) PHAuthorizationStatusDenied 用戶已經明顯拒絕過當前App訪問相片數據(用戶已經點擊過Don't Allow按鈕) PHAuthorizationStatusAuthorized 用戶已經允許過當前App訪問相片數據(用戶已經點擊過OK按鈕)
-
-
二 : 獲取系統的相冊圖片(一張或者多張)
UIImagePickerControllerSourceTypePhotoLibrary, 從所有相冊中選擇圖片 UIImagePickerControllerSourceTypeCamera, 利用照相機拍一張圖片(自定義照相機AVCaptureSession) UIImagePickerControllerSourceTypeSavedPhotosAlbum 從Moments相冊中選擇圖片
1.獲取一張相冊里的圖片(圖片 == 1)
獲取相冊中的圖片
-
1.單張
1>UIImagePickerController
2>AssetsLibrary
框架
3>Photos
框架- 2.多張(>=2張)
1>AssetsLibrary
框架
2>Photos
框架demo1:
- 點擊屏幕時,就跳轉到系統相冊進行選擇圖片(只能選擇一張照片)
@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]; }
//實現代理方法<UIImagePickerControllerDelegate> -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info { // 關閉選擇圖片界面 [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 { // ..... // 關閉選擇圖片界面 [picker dismissViewControllerAnimated:YES completion:nil]; }
2.獲取多張相冊里的圖片(圖片 >= 2)
用到框架和實現協議一些方法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; // 設置相冊的類型:相機膠卷 + 自定義相冊 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 { // 關閉圖片選擇界面 [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]; }]; } }
效果:
- 2.多張(>=2張)