美文网首页iOS移动开发进阶demodemo
iOS-自定义照片选择器+裁剪图片

iOS-自定义照片选择器+裁剪图片

作者: 向钱冲啊 | 来源:发表于2017-01-13 00:00 被阅读2783次

    这两天产品说我用系统的UIImagePickerController界面UI很丑,迫不得已下就选择了自定义一个照片选择器。实现效果如下图:

    demo中3张效果图.png
    实现步骤

    具体实现就两个步骤:
    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)

    相关文章

      网友评论

      • zero000:有demo吗
      • Daybreak_8f5f:你好 第一次打开相册会要求获取权限 ,获取不到图片 第二次就是正常的了
      • FastAbandon:第一次打开相册获取不到图片
      • 零下十一度:Connection to assetsd was interrupted or assetsd died 出现这个问题是怎么回事呢 楼主
      • DZIR:得到灵感,感谢分享

      本文标题:iOS-自定义照片选择器+裁剪图片

      本文链接:https://www.haomeiwen.com/subject/ozejbttx.html