IOS开发获取相册图片,并给图片编辑页面加上空心圆遮罩
先放效果图
IMG_1953.png1、获取图片,使用UIImagePickerController,sourcetype图片来源(UIImagePickerControllerSourceTypePhotoLibrary图库包含一些自己添加的图片,UIImagePickerControllerSourceTypeCamera相机,UIImagePickerControllerSourceTypeSavedPhotosAlbum相册)。
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
// imagePickerController.allowsEditing = true; 如果为true,会跳转到系统给的编辑页面,这里我们选择自定义编辑页面
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:true completion:nil];
选取完图片后在imagePickerController的代理方法里面收到回调信息,图片的信息都保存在返回的info字典里面。
其中UIImagePickerControllerOriginalImage关键字表示原图,UIImagePickerControllerReferenceURL表示原图的URL,可以通过Photos/Photos.h库中的PHAsset实例获取。
//选取图片后的代理回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
UIImage *originImage = info[@"UIImagePickerControllerOriginalImage"];
NSLog(@"info=%@",info);
//跳转自定义编辑页面
ImagePickerCropViewController *vc = [[ImagePickerCropViewController alloc] init];
vc.originImage = originImage;
[picker pushViewController:vc animated:true];
[vc maskCircleImage:^(UIImage *image) {
NSLog(@"获取到编辑后的图片");
}];
// 或者是通过Photos/Photos.h库PHAsset获取
//NSURL *imageAssetUrl = [info objectForKey:UIImagePickerControllerReferenceURL];
// PHFetchResult*result = [PHAsset fetchAssetsWithALAssetURLs:@[imageAssetUrl] options:nil];
// PHAsset *asset = [result firstObject];
// PHImageRequestOptions *phImageRequestOptions = [[PHImageRequestOptions alloc] init];
// [[PHImageManager defaultManager] requestImageDataForAsset:asset options:phImageRequestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
// //imageData
// }];
这样图片获取完成.
2、自定义编辑页面缩放图片,拿到图片后缩放,让图片的宽高最小值刚好等于中间的空心圆直径大小
//缩放比例,把宽和高的最小值缩放到圆的直径大小,让图片看起来在圆内
CGFloat scale = 1.0f;
CGFloat minFloat = self.originImage.size.width<self.originImage.size.height?self.originImage.size.width:self.originImage.size.height;
scale = minFloat/(CircleRadius*2);
self.cropImageView.frame = CGRectMake(0, 0, self.originImage.size.width/scale, self.originImage.size.height/scale);
然后将图片放在scrollview里面,利用scrollview的缩放功能进行缩放,记得让图片居于scrollview的contentsize可滑动范围的中间, 然后设置scrollview的contentofset偏移,让图片居于self.view的中间
//创建scroll用于缩放和滑动查看图片
UIScrollView *scroll = [[UIScrollView alloc]initWithFrame:frame];
scroll.bounces = YES;
//滑动范围就是scrollview的大小加上图片比圆多出来的部分
CGFloat contentSizeWidth = scroll.frame.size.width+(_cropImageView.frame.size.width-CircleRadius*2);
CGFloat contentSizeHeight = scroll.frame.size.height+(_cropImageView.frame.size.height-CircleRadius*2);
//设置scrollview的滑动范围
scroll.contentSize = CGSizeMake(contentSizeWidth,contentSizeHeight);
//设置图片在scrollview的滑动范围中心显示
self.cropImageView.center = CGPointMake(scroll.contentSize.width/2.0, scroll.contentSize.height/2.0);
//设置scrollview的偏移让图片刚好在view的中间
scroll.contentOffset = CGPointMake((_cropImageView.frame.size.width-CircleRadius*2)/2.0, (_cropImageView.frame.size.height-CircleRadius*2)/2.0);
scroll.delegate=self;
//设置最大伸缩比例
scroll.maximumZoomScale=2.0;
//设置最小伸缩比例
scroll.minimumZoomScale=1;
[self.view addSubview:scroll];
[scroll addSubview:self.cropImageView];
记得在scrollViewDidEndZooming代理方法里面让scrollview的contentsize滑动范围适应图片大小,否则会出现缩放完,scrollview无法滑动的情况。
3、添加遮罩,使用贝塞尔曲线画一个圆形路径,然后将路径添加到layer上面,填充规则选择kCAFillRuleEvenOdd。
填充规则kCAFillRuleEvenOdd,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部,记得计算的时候加上外部的rect边框。
填充规则kCAFillRuleNonZero,从0开始计数,路径顺时针穿过射线则计数加1,逆时针穿过射线则计数减1,
结果为0则是外部,看你绘制路径的时候选择顺时针还是逆时针,计算的时候记得包含rect的边框[UIBezierPath bezierPathWithRect:rect]。
//
UIBezierPath *path = [UIBezierPath bezierPathWithRect:rect];
CGFloat x = rect.size.width/2.0;
CGFloat y = rect.size.height/2.0;
CGFloat radius = CircleRadius;
//用贝塞尔曲线画圆,clockwise选择顺时针
UIBezierPath *cycle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(x, y)
radius:radius
startAngle:0.0
endAngle:2*M_PI
clockwise:1];
//添加圆的路径
[path appendPath:cycle];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = [path CGPath];
/*1、填充规则kCAFillRuleEvenOdd,要判断一个点是否在图形内,从该点作任意方向的一条射线,然后检测射线与图形路径的交点的数量。如果结果是奇数则认为点在内部,是偶数则认为点在外部,记得包含rect边框[UIBezierPath bezierPathWithRect:rect]
2、填充规则 kCAFillRuleNonZero,从0开始计数,路径顺时针穿过射线则计数加1,逆时针穿过射线则计数减1,
结果为0则是外部,看你绘制路径的时候选择顺时针还是逆时针记得包含rect的边框[UIBezierPath bezierPathWithRect:rect]*/
maskLayer.fillRule = kCAFillRuleEvenOdd;
maskLayer.fillColor = [UIColor blackColor].CGColor;
maskLayer.opacity = .5;//半透明填充
以上就是基本实现,总结一下过程,通过UIImagePickerController设置代理拿到图片或者图片的URL,然后进入到自定义的编辑页面,通过scrollview进行图片的缩放,通过贝塞尔曲线画圆形路径,然后用layer添加路径并填充完成遮罩,记得最后添加layer。
自定义剪裁页面参考:
IOS开发-自定义裁剪框并保存在相册
网友评论