iOS 图片剪裁(附demo下载)
作者:互联网
文章目录
#Demo下载地址
http://download.csdn.net/detail/lovechris00/9873031
Demo 说明
- 本代码参考 杨淑园 的 YSHYClipViewController;
- 可裁剪圆形、正方形、长方形(自己设置尺寸);
- 界面都搭建好,拿来即用;
由于mardown处理图片尺寸很麻烦,所以效果图见文章最下方。如有问题,欢迎反馈留言~!
基本功能描述
- 进入剪裁界面,图片适配剪裁框宽高。(根据尺寸比例,让图片的宽等于剪裁框宽度,或者高与之相等)。
- 为图片添加手势,和手势的代理。根据拖拽、捏合手势,来处理图片的放大、移动。
- 拖拽、捏合时,让图片处于裁剪范围内。暂时没有做旋转。
- 点击确定时,根据图片比例和位置,复制图片内容到画布,并输出画布。
- 通过代理,输出结果到调用的控制器。
剪裁界面布局
用贝塞尔绘制半透明蒙版
#pragma mark - 绘制裁剪框
-(void)drawClipPath
{
UIBezierPath *path= [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.view.mj_w, self.view.mj_h)];
CAShapeLayer *layer = [CAShapeLayer layer];
UIBezierPath *clipPath;
if (self.clipType == SQUARECLIP) {//方形
clipPath = [UIBezierPath bezierPathWithRect:self.clipFrame];
}else{
clipPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.clipFrame), CGRectGetMidY(self.clipFrame)) radius:_clipW * 0.5 startAngle:0 endAngle:2*M_PI clockwise:NO];
}
[path appendPath:clipPath];
[path setUsesEvenOddFillRule:YES];
layer.path = path.CGPath;
layer.fillRule = kCAFillRuleEvenOdd;
layer.fillColor = [[UIColor blackColor] CGColor];
layer.opacity = 0.5;
[_overView.layer addSublayer:layer];
//添加白线
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = _overView.bounds;
shapeLayer.path = clipPath.CGPath;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 1.0f;
shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
[_overView.layer addSublayer:shapeLayer];
}
拖拽捏合图片
根据拖拽中 [panGesture translationInView:view.superview];改变图片位置
根据捏合中的 pinGesture.scale 改变图片大小。
##考虑事项:
###捏合后,图片宽、高,小于裁剪框的宽高
处理方式:如果图片宽度imgW 小于裁剪框的宽 clipW,则让图片 imgW = clipW; 如果处理后 图片高度imgH 小于裁剪框高度 clipH , 则让 imgH = clipH。
针对不同尺寸的裁剪框,我们要让图片宽高中的最小项,大于裁剪框宽高中的最大项。所以可以根据宽高比来方便判断。
重新设置尺寸的方法如下:
#pragma mark -- 处理图片大小
-(CGSize )handleScale
{
CGFloat oriRate = _image.size.width / _image.size.height;
CGFloat clipRate = _clipW / _clipH;
CGSize resultSize;
if (oriRate > clipRate) {
resultSize.height = _clipH;
resultSize.width = oriRate * _clipH;
}else{
resultSize.width = _clipW;
resultSize.height = _clipW / oriRate;
}
return resultSize;
}
###移动后、缩小后,图片四角不在裁剪框内;
经过上述操作,图片尺寸不会小于裁剪框尺寸。所以只需要判断四角的x,y值。
如果左上角在框内,则让x = clipX,同理亦然。具体代码如下:
#pragma mark -- 缩放结束后 确保图片在裁剪框内
-(CGRect )handlePosition:(UIView *)view
{
// 图片.top < 裁剪框.top
if(view.frame.origin.y > self.clipFrame.origin.y)
{
CGRect viewFrame = view.frame;
viewFrame.origin.y = self.clipFrame.origin.y;
view.frame = viewFrame;
}
// 图片.left < 裁剪框.left
if(view.frame.origin.x > self.clipFrame.origin.x)
{
CGRect viewFrame = view.frame;
viewFrame.origin.x = self.clipFrame.origin.x;
view.frame = viewFrame;
}
// 图片.right < 裁剪框.right
if(CGRectGetMaxX(view.frame)< CGRectGetMaxX(self.clipFrame))
{
CGFloat right =CGRectGetMaxX(view.frame);
CGRect viewFrame = view.frame;
CGFloat space = CGRectGetMaxX(self.clipFrame) - right;
viewFrame.origin.x+=space;
view.frame = viewFrame;
}
// 图片.bottom < 裁剪框.bottom
if(CGRectGetMaxY(view.frame) < CGRectGetMaxY(self.clipFrame))
{
CGRect viewFrame = view.frame;
CGFloat space = CGRectGetMaxY(self.clipFrame) - (CGRectGetMaxY(view.frame));
viewFrame.origin.y +=space;
view.frame = viewFrame;
}
return view.frame;
}
剪裁方法
#pragma mark - 裁剪获取图片
-(UIImage *)getClippedImage
{
CGFloat rationScale = (_imageView.mj_w /_image.size.width);
CGFloat origX = (self.clipFrame.origin.x - _imageView.frame.origin.x) / rationScale;
CGFloat origY = (self.clipFrame.origin.y - _imageView.frame.origin.y) / rationScale;
CGFloat oriWidth = _clipW / rationScale;
CGFloat oriHeight = _clipH / rationScale;
CGRect myRect = CGRectMake(origX, origY, oriWidth, oriHeight);
CGImageRef imageRef = CGImageCreateWithImageInRect(_image.CGImage, myRect);
UIGraphicsBeginImageContext(myRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, myRect, imageRef);
UIImage * clipImage = [UIImage imageWithCGImage:imageRef];
UIGraphicsEndImageContext();
if(self.clipType == CIRCULARCLIP){
return [self clipCircularImage:clipImage];
}
return clipImage;
}
#pragma mark -- 裁剪图片为圆形效果
-(UIImage *)clipCircularImage:(UIImage *)image
{
CGFloat arcCenterX = image.size.width/ 2;
CGFloat arcCenterY = image.size.height / 2;
UIGraphicsBeginImageContext(image.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath(context);
CGContextAddArc(context, arcCenterX , arcCenterY, image.size.width/ 2 , 0.0, 2*M_PI, NO);
CGContextClip(context);
CGRect myRect = CGRectMake(0 , 0, image.size.width , image.size.height);
[image drawInRect:myRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
效果如下:
标签:origin,demo,self,裁剪,iOS,剪裁,图片,frame,view 来源: https://blog.csdn.net/lovechris00/article/details/73381530