1. 程式人生 > >iOS開啟相簿多選、圖片瀏覽器、圖片裁剪

iOS開啟相簿多選、圖片瀏覽器、圖片裁剪

資源類

  • 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

圖片裁剪框架: