iOS-自定义照片选择器+裁剪图片
2017-01-13 本文已影响2783人
向钱冲啊
demo中3张效果图.png这两天产品说我用系统的
UIImagePickerController
界面UI很丑,迫不得已下就选择了自定义一个照片选择器。实现效果如下图:
实现步骤
具体实现就两个步骤:
1.用系统的<Photos/Photos.h>
框架异步获取到相册中的所有图片(包括原图和缩略图),然后用collectionview
进行展示缩略图。
2.再对获取到相册图片的原图进行裁剪,分圆形裁剪和方形裁剪。裁剪框路径使用贝塞尔曲线分别设置的路径
//设置圆形路径。
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
//设置带有圆角的矩形路径
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius ```
######具体代码
写了个```UIImage+Extension.h```的分类,异步并发获取到所有图片
/**
获取系统相册中所有的缩略图 和原图
缩略图 尺寸 大约 {32.5,60} (allSmallImageArray 回调获取到的缩略图 图片数组)
原图 尺寸 大约 屏幕等大 (allOriginalImageArray 回调获取到的大图 图片数组)
*/
- (void)async_getLibraryPhoto:(void(^)(NSArray <UIImage *> *allSmallImageArray))smallImageCallBack
allOriginalImageCallBack:(void(^)(NSArray <UIImage *> *allOriginalImageArray))allOriginalImageCallBack
{
static UIImage *image;image = [UIImage new];
dispatch_queue_t concurrencyQueue = dispatch_queue_create("getLibiaryAllImage-queue",
DISPATCH_QUEUE_CONCURRENT);
// task 1 : 获得相册中所有 缩略图
dispatch_async(concurrencyQueue, ^{
NSMutableArray *smallPhotoArray = [NSMutableArray array];
[smallPhotoArray addObjectsFromArray:[UIImage getImageWithScaleImage:image isOriginalPhoto:NO]];
dispatch_async(dispatch_get_main_queue(), ^{
if (smallImageCallBack) {
smallImageCallBack([smallPhotoArray copy]);
}
});
});
// task 2 : 获得相册中所有 原图
dispatch_async(concurrencyQueue, ^{
NSMutableArray *allOriginalPhotoArray = [NSMutableArray array];
[allOriginalPhotoArray addObjectsFromArray:[UIImage getImageWithScaleImage:image isOriginalPhoto:YES]];
dispatch_async(dispatch_get_main_queue(), ^{
if (allOriginalImageCallBack) {
allOriginalImageCallBack([allOriginalPhotoArray copy]);
}
});
});
} - (NSArray <UIImage *> *)getImageWithScaleImage:(UIImage *)image isOriginalPhoto:(BOOL)isOriginalPhoto
{
NSMutableArray *photoArray = [NSMutableArray array];
// 获得所有的自定义相册
PHFetchResult<PHAssetCollection *> *assetCollections = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
// 遍历所有的自定义相册
for (PHAssetCollection *assetCollection in assetCollections) {
[photoArray addObjectsFromArray:[image enumerateAssetsInAssetCollection:assetCollection original:isOriginalPhoto]];
}
// 获得相机胶卷相册
PHAssetCollection *cameraRoll = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil].lastObject;
[photoArray addObjectsFromArray:[image enumerateAssetsInAssetCollection:cameraRoll original:isOriginalPhoto]];
return photoArray;
}
/**
- 遍历相簿中的所有图片
- @param assetCollection 相册
- @param original 是否需要原图
*/
- (NSArray <UIImage *> *)enumerateAssetsInAssetCollection:(PHAssetCollection *)assetCollection original:(BOOL)original
{
NSMutableArray *array = [NSMutableArray array];
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
// 同步获得图片
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) {
[array addObject:result];
}];
}
return array;
} ```
然后自定义一个照片控制器继承于UICollectionViewController
,设置代理回调方法和初始化方法
HPPhotoPickerController.h
#import <UIKit/UIKit.h>
@class HPPhotoPickerController;
@protocol HPPhotoPickerControllerDelegate <NSObject>
- (void)imagePickerController:(HPPhotoPickerController *)picker didFinishPickingWithImage:(UIImage *)image;
@end
@interface HPPhotoPickerController : UICollectionViewController
@property (nonatomic ,weak) id <HPPhotoPickerControllerDelegate> delegate;
/**
照片 选择控制器 初始化 方法
@param delegate 控制器代理
@param isOvalClip 裁剪方式 YES : 正方形裁剪 NO :圆形裁剪
@param layout 控制器 layout
@return self
*/
- (instancetype)initWithDelegate:(id)delegate
isOvalClip:(BOOL)isOvalClip
flowLayout:(UICollectionViewFlowLayout *)layout;
@end ```
```HPPhotoPickerController.m```获取图片然后去下个界面进行裁剪
#import "HPPhotoPickerController.h"
#import "UIImage+Extension.h"
#import "HPPhotoPickerDetailController.h"
@class HPPickerImageViewCell;
@interface HPPhotoPickerController ()<UICollectionViewDelegateFlowLayout>
{
BOOL _isOvalClip;
}
@property (nonatomic ,strong) NSMutableArray *smallphotoArray;
@property (nonatomic ,strong) NSMutableArray *bigPhotoArray;
@end
@implementation HPPhotoPickerController
static NSString * const reuseIdentifier = @"Cell";
- (void)getData
{
[UIImage async_getLibraryPhoto:^(NSArray<UIImage *> *allSmallImageArray) {
NSLog(@"***小**%ld",allSmallImageArray.count);
[self.smallphotoArray addObjectsFromArray:allSmallImageArray];
[self.collectionView reloadData];
} allOriginalImageCallBack:^(NSArray<UIImage *> *allOriginalImageArray) {
NSLog(@"***大**%ld",allOriginalImageArray.count);
[self.bigPhotoArray addObjectsFromArray:allOriginalImageArray];
}];
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.smallphotoArray.count > 0) {
return self.smallphotoArray.count;
}
return 0;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
HPPickerImageViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.photo.image = self.smallphotoArray[indexPath.row];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
//判断大于0,是做安全处理,大图加载慢,防止还没加载完毕就push,造成数据传空
if (self.bigPhotoArray.count > 0) {
HPPhotoPickerDetailController *detailVC = [[HPPhotoPickerDetailController alloc]initWithImage:self.bigPhotoArray[indexPath.row] delegate:self];
detailVC.ovalClip = _isOvalClip;
[self.navigationController pushViewController:detailVC animated:YES];
}
} ```
裁剪图片的控制器是参照这位同学写的[iOS实现头像裁剪(方或圆)功能,支持缩放拖曳](http://www.jianshu.com/p/d9ca82c1834c)
[这是demo地址,大家加油,开源使人进步。。。](https://github.com/leijianmin/PhotoPickerController)