人一切的痛苦,本質(zhì)上都是對(duì)自己的無(wú)能的憤怒。
1.相冊(cè)訪問權(quán)限
2.相冊(cè)中圖片變化的監(jiān)聽
3.讀取相冊(cè)中的圖片
4.將圖片保存到相冊(cè)
相冊(cè)訪問權(quán)限
使用系統(tǒng)相冊(cè)的時(shí)候,首先判斷是否有權(quán)限,沒有權(quán)限的話,可以彈出提示框。
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status == PHAuthorizationStatusRestricted ||
status == PHAuthorizationStatusDenied) {
// 這里便是無(wú)訪問權(quán)限
//可以彈出個(gè)提示框,叫用戶去設(shè)置打開相冊(cè)權(quán)限
} else {
//這里就是用權(quán)限
}
相冊(cè)中圖片變化的監(jiān)聽
相冊(cè)監(jiān)聽中的回調(diào)方法是在 子線程 中的,因此要改變UI布局的話,必須回到主線程
[[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self]; //創(chuàng)建監(jiān)聽者
[[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self]; //移除監(jiān)聽者
//相冊(cè)變化回調(diào)
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
dispatch_sync(dispatch_get_main_queue(), ^{
//修改UI
});
}
獲取相冊(cè)中的圖片
** 幾個(gè)常用的類 **
**PHAsset **: 代表照片庫(kù)中的一個(gè)資源,跟 ALAsset 類似,通過 PHAsset 可以獲取和保存資源。每個(gè)PHAsset就是一張圖片的詳細(xì)信息,包括圖片、位置、時(shí)間等。
** PHFetchOptions **: 獲取資源時(shí)的參數(shù),可以傳 nil,即使用系統(tǒng)默認(rèn)值。
** PHFetchResult **: 表示一系列的資源集合,也可以是相冊(cè)的集合。
** PHAssetCollection **: 表示一個(gè)相冊(cè)或者一個(gè)時(shí)刻,或者是一個(gè)智能相冊(cè)(系統(tǒng)提供的特定的一系列相冊(cè),例如:最近刪除,視頻列表,收藏等等)。
** PHImageManager **: 用于處理資源的加載,加載圖片的過程帶有緩存處理,可以通過傳入一個(gè) PHImageRequestOptions 控制資源的輸出尺寸等規(guī)格。
** PHImageRequestOptions **: 如上面所說,控制加載圖片時(shí)的一系列參數(shù)。
// 獲取所有資源的集合,并按資源的創(chuàng)建時(shí)間排序
PHFetchOptions *options = [[PHFetchOptions alloc] init];
options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
//獲取相機(jī)膠卷所有圖片
PHFetchResult *assets = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
//設(shè)置顯示模式
/*
PHImageRequestOptionsResizeModeNone //選了這個(gè)就不會(huì)管傳如的size了 ,要自己控制圖片的大小,建議還是選Fast
PHImageRequestOptionsResizeModeFast //根據(jù)傳入的size,迅速加載大小相匹配(略大于或略小于)的圖像
PHImageRequestOptionsResizeModeExact //精確的加載與傳入size相匹配的圖像
*/
option.resizeMode = PHImageRequestOptionsResizeModeFast;
option.synchronous = NO;
option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
CGFloat scale = [UIScreen mainScreen].scale;
CGSize screenSize = [UIScreen mainScreen].bounds.size;
typeof(self)weakSelf = self;
for (PHAsset *asset in assets) {
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(screenSize.width*scale, screenSize.height*scale) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
//我這里用個(gè)模型接儲(chǔ)存了圖片的 localIdentifier 和圖片本身
//還有很多信息,根據(jù)自己的需求來(lái)取
CellModel * model = [CellModel new];
model.localIdentifier = asset.localIdentifier;
model.image = [UIImage imageWithData:UIImageJPEGRepresentation(result, 0.5)];
[weakSelf.cellImageArray addObject:model];
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf reloadData];
});
}];
}
將圖片保存到相冊(cè)
-
方法一:
- 優(yōu)點(diǎn):簡(jiǎn)單快捷
- 缺點(diǎn):無(wú)法直接保存到自定義相冊(cè)
- (IBAction)savePhoto {
// - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
//只能保存到相機(jī)膠卷(不能保存到自定義相冊(cè))
UIImageWriteToSavedPhotosAlbum(self.Photo.image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
//回調(diào)判斷保存是否成功
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) {
//保存失敗
}else{
//保存成功
}
}
- ** 方法二: **
- 優(yōu)點(diǎn):能夠保存到任何相冊(cè)
- 缺點(diǎn):沒有第一種方法簡(jiǎn)單
// 添加圖片到自己相冊(cè)
- (void)savePhoto
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// 1.創(chuàng)建圖片請(qǐng)求類(創(chuàng)建系統(tǒng)相冊(cè)中新的圖片)PHAssetCreationRequest
// 把圖片放在系統(tǒng)相冊(cè)
PHAssetCreationRequest *assetCreationRequest = [PHAssetCreationRequest creationRequestForAssetFromImage:_imageView.image];
// 2.創(chuàng)建相冊(cè)請(qǐng)求類(修改相冊(cè))PHAssetCollectionChangeRequest
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = nil;
// 獲取之前相冊(cè)
PHAssetCollection *assetCollection = [self fetchAssetCollection:@"百思不得姐"];
// 判斷是否已有相冊(cè)
if (assetCollection) {
// 如果存在已有同名相冊(cè) 指定這個(gè)相冊(cè),創(chuàng)建相冊(cè)請(qǐng)求修改類
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
} else { //不存在,創(chuàng)建新的相冊(cè)
assetCollectionChangeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:@"百思不得姐"];
}
// 3.把圖片添加到相冊(cè)中
// NSFastEnumeration:以后只要看到這個(gè),就可以表示數(shù)組
//assetCreationRequest.placeholderForCreatedAsset 圖片請(qǐng)求類占位符(相當(dāng)于一個(gè)內(nèi)存地址)
//因?yàn)閏reationRequestForAssetFromImage方法是異步實(shí)行的,在這里不能保證 assetCreationRequest有值
[assetCollectionChangeRequest addAssets:@[assetCreationRequest.placeholderForCreatedAsset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
[SVProgressHUD showSuccessWithStatus:@"保存成功"];
} else {
[SVProgressHUD showErrorWithStatus:@"保存失敗"];
}
}];
}
// 指定相冊(cè)名稱,獲取相冊(cè)
- (PHAssetCollection *)fetchAssetCollection:(NSString *)title
{
// 獲取相簿中所有自定義相冊(cè)
PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
遍歷相冊(cè),判斷是否存在同名的相冊(cè)
for (PHAssetCollection *assetCollection in result) {
if ([title isEqualToString:assetCollection.localizedTitle]) { 存在,就返回這個(gè)相冊(cè)
return assetCollection;
}
}
return nil;
}