iOS開啟相簿多選、圖片瀏覽器、圖片裁剪
阿新 • • 發佈:2019-02-03
資源類
- PHPhotoLibrary 是一個資源庫。能夠獲取相簿許可權以及對相簿的操作,與AL不同,它不能獲取資源物件哦.
- PHFetchResult 是一個結果集,一個泛型類。通過方法獲取到的相簿或者資源組就是被封裝成該類返回.
- PHAssetCollection 是一個資源集合物件。其實它就是一個相簿的概念,可通過
類方法
獲得想要的相簿集合,繼承自PHCollection. - PHCollectionList 是一個資源集合列表物件。剛接觸時以為它是存放PHCollection物件的集合,後來才知道,如果想要通過地點以及時間分組的話,請使用這個類替代PHAssetCollection吧,用法與PHAssetCollection類似,同樣是繼承自PHCollection.
- PHAsset 是一個獨立的資源物件。可以通過
類方法
對PHCollection物件進行遍歷,獲得存放Asset物件的結果集,可以直接獲得資源的規格資料,若想獲得圖片以及原圖等資源,需要配合PHImageManager物件,繼承自PHObject.
工具類
- PHFetchOptions 一個遍歷配置類。一般情況下,當存在遍歷方法的時候就存在這個型別的引數,裡面含有謂詞、遍歷順序等屬性,可以通過設定這些屬性,完成不同的遍歷.
- PHImageManager 是一個負責渲染資源的類。比如獲得PHAsset物件的原圖等操作需要使用該類.
- PHCachingImageManager 繼承自PHImageManager,可以對請求的資源物件進行快取,這樣再次獲取時就不需要重新渲染,在加快獲取速度的同時也降低了CPU的壓力,這裡最好對快取的PHImageRequestID進行一下記錄,防止同一資源被無限快取的尷尬.
- PHImageRequestOptions 是一個資源請求的配置類。通常在使用PHImageManager對某個資源進行請求時都會存在此型別的引數,可以在請求資源時對該物件進行設定,獲得想要的結果,比如原圖..
請求類
- 請求類不能獨立使用,要想發揮作用,需要與PHPhotoLibrary物件配合使用.
- PHAssetCollectionChangeRequest 集合變化請求類,負責對PHAssetCollection物件的操作
- PHCollectionListChangeRequest 集合變化請求類,負責PHCollectionList物件的操作
- PHAssetChangeRequest 資源變化請求類,負責PHAsset物件的操作
/**
* 獲得所有相簿的原圖
*/
- (void)getOriginalImages
{
// 獲得所有的自定義相簿
PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 遍歷所有的自定義相簿
for (PHAssetCollection *assetCollection in assetCollections) {
[self enumerateAssetsInAssetCollection:assetCollection original:YES];
}
// 獲得相機膠捲
PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
[self enumerateAssetsInAssetCollection:cameraRoll original:YES];
}
/**
* 獲得所有相簿中的縮圖
*/
- (void)getThumbnailImages
{
// 獲得所有的自定義相簿
PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 遍歷所有的自定義相簿
for (PHAssetCollection *assetCollection in assetCollections) {
[self enumerateAssetsInAssetCollection:assetCollection original:NO];
}
// 獲得相機膠捲
PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
[self enumerateAssetsInAssetCollection:cameraRoll original:NO];
}
/**
* 遍歷相簿中的所有圖片
*
* @param assetCollection 相簿
* @param original 是否要原圖
*/
- (void)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original
{
NSLog(@"相簿名:%@", assetCollection.localizedTitle);
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// 同步獲得圖片, 只會返回1張圖片
// options.synchronous = YES;
// 獲得某個相簿中的所有PHAsset物件
PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
for (PHAsset *asset in assets) {
// 是否要原圖
CGSize size = original ? CGSizeMake(asset.pixelWidth, asset.pixelHeight) : CGSizeZero;
// 從asset中獲得圖片
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
NSLog(@"%@", result);
[self.imageArr addObject:result];//把照片存發放到陣列,然後用collectionview展示出來,可以做成多選相簿
}];
}
[self setCollectionView];
}
/**
* 獲得相機膠捲中的所有圖片
*/
- (void)getImagesFromCameraRoll
{
// 獲得相機膠捲中的所有圖片
PHFetchResult<PHAsset *> *assets = [PHAsset fetchAssetsWithOptions:nil];
__block int count = 0;
for (PHAsset *asset in assets) {
[[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(asset.pixelWidth, asset.pixelHeight) contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
}];
}
}
//相簿多選
-(void)AlumLibrary{
QBImagePickerController *imagePickerController = [QBImagePickerController new];
imagePickerController.delegate = self;
imagePickerController.allowsMultipleSelection = YES;//是否可以多選
imagePickerController.maximumNumberOfSelection = 6;//最大選擇數
imagePickerController.minimumNumberOfSelection=3;//最小選擇數
//設定每行顯示的影象數量
imagePickerController.numberOfColumnsInPortrait = 4;//豎屏下每行4個
imagePickerController.numberOfColumnsInLandscape = 7;//橫愜意下每行7個
imagePickerController.showsNumberOfSelectedAssets = YES;//底部顯示的選擇了幾張圖片
imagePickerController.prompt = @"Select the photos you want to upload!";//最頂部的那一個行字
[self presentViewController:imagePickerController animated:YES completion:NULL];
}
-(void)photoBrowserDidFinishModalPresentation:(MWPhotoBrowser *)photoBrowser{
NSLog(@"dfdscfd");
}
//確認選擇照片完畢
- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didFinishPickingAssets:(NSArray *)assets {
for (PHAsset *asset in assets) {
}
NSLog(@"確認選擇照片完畢");
[self dismissViewControllerAnimated:YES completion:NULL];
}
//取消選擇
- (void)qb_imagePickerControllerDidCancel:(QBImagePickerController *)imagePickerController {
[self dismissViewControllerAnimated:YES completion:NULL];
}
- (BOOL)qb_imagePickerController:(QBImagePickerController *)imagePickerController shouldSelectAsset:(PHAsset *)asset{
return YES;
}
//選中圖片
- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didSelectAsset:(PHAsset *)asset{
NSLog(@"選擇了圖片");
}
//取消選中圖片
- (void)qb_imagePickerController:(QBImagePickerController *)imagePickerController didDeselectAsset:(PHAsset *)asset{
NSLog(@"取消選擇圖片");
}
相簿多選框架:
//相簿多選
-(void)AlumLibrary{
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:9 delegate:self];
// 你可以通過block或者代理,來得到使用者選擇的照片.
[imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage, id asset) {
}];
[self presentViewController:imagePickerVc animated:YES completion:nil];
}
//選擇完照片
-(void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos{
NSLog(@"選擇完照片");
}
//取消
-(void)tz_imagePickerControllerDidCancel:(TZImagePickerController *)picker{
NSLog(@"取消");
}
//選擇完視訊
-(void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(id)asset{
NSLog(@"選擇完視訊");
}
-(void)mbprogress{
[self.photos addObject: [[MWPhoto alloc]initWithImage:self.imageArr[0]]];
[self.photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"https://www.baidu.com/img/baidu_jgylogo3.gif"]]];
[self.photos addObject:[MWPhoto photoWithURL:[NSURL URLWithString:@"https://www.baidu.com/img/baidu_jgylogo3.gif"]]];
MWPhoto *video = [MWPhoto photoWithURL:[NSURL URLWithString:@"http://www.ddb.cn/public/apk/spjc.mp4"]];
video.videoURL = [[NSURL alloc] initWithString:@"http://www.ddb.cn/public/apk/spjc.mp4"];
[self.photos addObject:video];
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.delegate=self;
browser.displayActionButton = YES;
browser.displayNavArrows = NO;
browser.displaySelectionButtons = NO;
browser.zoomPhotosToFill = YES;
browser.alwaysShowControls = YES;
browser.enableGrid = YES;
browser.startOnGrid = YES;
browser.autoPlayOnAppear = NO;
browser.customImageSelectedIconName = @"eightewm";
browser.customImageSelectedSmallIconName = @"eightewm";
[browser setCurrentPhotoIndex:0];
[browser showNextPhotoAnimated:YES];
[browser showPreviousPhotoAnimated:YES];
// Present
[self.navigationController pushViewController:browser animated:YES];
}
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return self.photos.count;
}
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex:(NSUInteger)index {
if (index < self.photos.count) {
return [self.photos objectAtIndex:index];
}
return nil;
}
//呼叫下面的方法會網格顯示,網格顯示的時候也可以切換到大圖
- (id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index{
return [_photos objectAtIndex:index];
}
//當點選右下角的分享按鈕的時候觸下面的方法
- (void)photoBrowser:(MWPhotoBrowser *)photoBrowser actionButtonPressedForPhotoAtIndex:(NSUInteger)index {
NSLog(@"點選you下角分享按鈕的時候出發,這裡可以做自己的事情");
}
//圖片未釋出,本地瀏覽
-(void)localImage{
[self.imageArr addObject:[UIImage imageNamed:@"eightewm"]];
[self.imageArr addObject:[UIImage imageNamed:@"firstewm"]];
[self.imageArr addObject:[UIImage imageNamed:@"fiveewm"]];
[self.imageArr addObject:[UIImage imageNamed:@"eightewm"]];
// 2.1 設定本地圖片
PYPhotosView *photosView = [PYPhotosView photosViewWithImages:self.imageArr];
// 3. 設定代理
photosView.delegate = self;
// 4. 新增photosView
[self.view addSubview:photosView];
}
//圖片瀏覽
-(void)liulanImgae{
//圖片瀏覽需要傳入的是UIImageView陣列,未釋出狀態預覽傳入的是UIImage陣列
UIImageView *imgeV=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"eightewm"]];
imgeV.frame=CGRectMake(0, 0, 100, 100);
UIImageView *imgeV1=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"firstewm"]];
imgeV.frame=CGRectMake(0, 0, 100, 100);
UIImageView *imgeV2=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"fiveewm"]];
imgeV.frame=CGRectMake(0, 0, 100, 100);
UIImageView *imgeV3=[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"eightewm"]];
imgeV.frame=CGRectMake(0, 0, 100, 100);
[self.imageArr addObject:imgeV];
[self.imageArr addObject:imgeV1];
[self.imageArr addObject:imgeV2];
[self.imageArr addObject:imgeV3];
// 1. 建立photoBroseView物件
PYPhotoBrowseView *photoBroseView = [[PYPhotoBrowseView alloc] init];
// 2.1 設定圖片源(UIImageView)陣列
photoBroseView.sourceImgageViews = self.imageArr;
// 2.2 設定初始化圖片下標(即當前點選第幾張圖片)
photoBroseView.currentIndex = 2;
// 3.顯示(瀏覽)
[photoBroseView show];
}
//瀏覽網路圖片
-(void)lookNetImage{
// 1. 建立縮圖圖片連結陣列
NSMutableArray *thumbnailImageUrls = [NSMutableArray array];
// 新增圖片(縮圖)連結
[thumbnailImageUrls addObject:@""];
[thumbnailImageUrls addObject:@""];
[thumbnailImageUrls addObject:@""];
// 1.2 建立原圖圖片連結陣列
NSMutableArray *originalImageUrls = [NSMutableArray array];
// 新增圖片(原圖)連結
[originalImageUrls addObject:@""];
[originalImageUrls addObject:@""];
[originalImageUrls addObject:@""];
// 2. 建立一個photosView
PYPhotosView *photosView = [PYPhotosView photosViewWithThumbnailUrls:thumbnailImageUrls originalUrls:originalImageUrls];
// 3. 新增photosView
[self.view addSubview:photosView];
}
自定義的裁剪:
-----------自定義裁剪框的步驟:-----------
1.當我們實現了UIImagePickerController的代理後,需要在 imagePickerController:didFinishPickingMediaWithInfo:
imagePickerController.allowsEditing = true; 如果為true,就不會展現我們自己的裁剪檢視了,就無法自定義了
2.跳轉到自定義的控制器中去,吧從相簿中的獲取的圖片傳遞到控制器中;
UIImage *originImage = info[@"UIImagePickerControllerOriginalImage"];
ImagePickerCropViewController *vc = [[ImagePickerCropViewController alloc] init];
vc.originImage = originImage;
[picker pushViewController:vc animated:true];
3.在控制器中用一個Imageview顯示圖片,然後給imageview新增手勢;實現縮放;最後儲存;
************
#import "ViewController.h"
#import "ImagePickerCropViewController.h"
@interface ViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (IBAction)choosePhotot:(id)sender {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
// imagePickerController.allowsEditing = true; 如果為true,就不會展現我們自己的裁剪檢視了,就無法自定義了
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:true completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *originImage = info[@"UIImagePickerControllerOriginalImage"];
ImagePickerCropViewController *vc = [[ImagePickerCropViewController alloc] init];
vc.originImage = originImage;
[picker pushViewController:vc animated:true];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:true completion:nil];
}
@end
#import <UIKit/UIKit.h>
@interface ImagePickerCropViewController : UIViewController
@property (nonatomic, strong) UIImage *originImage;
@end
#import "ImagePickerCropViewController.h"
@interface ImagePickerCropViewController ()
@property (nonatomic, strong) UIImageView *cropImageView;
@end
@implementation ImagePickerCropViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(save)];
self.navigationItem.rightBarButtonItem = item;
CGRect frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height - 44);
self.cropImageView = [[UIImageView alloc] initWithFrame:frame];
_cropImageView.contentMode = UIViewContentModeScaleAspectFit;
[_cropImageView setImage:self.originImage];
_cropImageView.userInteractionEnabled = true;
[self.view addSubview:_cropImageView];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[self.cropImageView addGestureRecognizer:pan];
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[self.cropImageView addGestureRecognizer:pinch];
UIView *maskView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
maskView.center = self.view.center;
maskView.backgroundColor = [UIColor clearColor];
maskView.layer.borderWidth = 0.5;
maskView.layer.borderColor = [UIColor whiteColor].CGColor;
[self.view addSubview:maskView];
}
- (void)handlePinch:(UIPinchGestureRecognizer *)recognizer {
CGFloat scale = recognizer.scale;
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, scale, scale); //在已縮放大小基礎下進行累加變化;區別於:使用 CGAffineTransformMakeScale 方法就是在原大小基礎下進行變化
recognizer.scale = 1.0;
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state != UIGestureRecognizerStateEnded && recognizer.state != UIGestureRecognizerStateFailed){
CGPoint translation = [recognizer translationInView:self.view];
CGPoint center = self.cropImageView.center;
self.cropImageView.center = CGPointMake(center.x + translation.x, center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
}
- (UIImage *)captureScreen {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
img = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(img.CGImage, CGRectMake((self.view.center.x-100)*2+2, (self.view.center.y-100)*2+2, 400-4, 400-4))];
UIGraphicsEndImageContext();
return img;
}
- (void)save {
UIImageWriteToSavedPhotosAlbum([self captureScreen], nil, nil, nil);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
@end
圖片裁剪框架: