以下內(nèi)容是如何把APP中的圖片保存到相冊(cè)中和如何在相冊(cè)中選取圖片(一張或多張)
一: 把軟件中的圖片保存到系統(tǒng)相冊(cè)或者保存到自己創(chuàng)建的相冊(cè)中
方式一:
demo:
保存圖片到系統(tǒng)相冊(cè),這只是簡(jiǎn)單的把圖片保存到系統(tǒng)相冊(cè)中,

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

-
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];
}];
}
}
效果:
