Quartz2D-带有边框的图片裁剪AND截屏

Posted by Chen on September 24, 2016

# #带有边框的图片裁剪 具体实现思路:

1.假设边框宽度为BorderW 2.开启的图片上下文的尺寸就应该是原始图片的宽高分别加上两倍的BorderW,这样开启的目的是为了不让原始图片变形. 3.在上下文上面添加一个圆形填充路径.位置从0,0点开始,宽高和上下文尺寸一样大.设置颜色为要设置的边框颜色. 4.继续在上下文上面添加一个圆形路径,这个路径为裁剪路径. 它的x,y分别从BorderW这个点开始.宽度和高度分别和原始图片的宽高一样大. 将绘制的这个路径设为裁剪区域. 5.把原始路径绘制到上下文当中.绘制的位置和是裁剪区域的位置相同,x,y分别从border开始绘制. 6.从上下文状态当中取出图片. 7.关闭上下文状态.

代码

. 裁剪

//0.加载图片
UIImage *image = [UIImage imageNamed:@"阿狸头像"];
//1.开启跟原始图片一样大小的上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//2.设置一个圆形裁剪区域
//2.1绘制一个圆形
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//2.2.把圆形的路径设置成裁剪区域
[path addClip];//超过裁剪区域以外的内容都给裁剪掉
//3.把图片绘制到上下文当中(超过裁剪区域以外的内容都给裁剪掉)
[image drawAtPoint:CGPointZero];
//4.从上下文当中取出图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//5.关闭上下文
UIGraphicsEndImageContext();
self.imageV.image = newImage;

. 带边框

/**
* 生成一张带有边框的圆形图片
*
* @param borderW 边框宽度
* @param borderColor 边框颜色
* @param image 要添加边框的图片
*
* @return 生成的带有边框的圆形图片
*/
+ (UIImage *)imageWithBorder:(CGFloat)borderW color:(UIColor *)borderColor image:(UIImage *)image{
//0.加载图片
//UIImage *image = [UIImage imageNamed:@"阿狸头像"];
//1.确定边框宽度
//CGFloat borderW = 5;
//2.开启一个上下文
CGSize size = CGSizeMake(image.size.width + 2 * borderW, image.size.height + 2 * borderW);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
//3.绘制大圆,显示出来
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];
[borderColor set];
[path fill];
//4.绘制一个小圆,把小圆设置成裁剪区域
UIBezierPath *clipPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderW, borderW, image.size.width, image.size.height)];
[clipPath addClip];
//5.把图片绘制到上下文当中
[image drawAtPoint:CGPointMake(borderW, borderW)];
//6.从上下文当中取出图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//7.关闭上下文
UIGraphicsEndImageContext();
return newImage;
}

# #截屏 截屏效果实现具体思路为: 把UIView的东西绘制图片上下文当中,生成一张新的图片. 注意: UIView上的东西是不能直接画到上下文当中的. UIView之所以能够显示是因为内部的一个层(layer),所以我要把层上的东西渲染到UIView上面的. 怎样把图层当中的内容渲染到上下文当中? 直接调用layer的renderInContext:方法 renderInContext:带有一个参数, 就是要把图层上的内容渲染到哪个上下文. 截屏具体实现代码为:

1.开启一个图片上下文 UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0); 获取当前的上下文. CGContextRef ctx = UIGraphicsGetCurrentContext(); 2.把控制器View的内容绘制上下文当中. [self.view.layer renderInContext:ctx]; 3.从上下文当中取出图片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 4.关闭上下文. UIGraphicsEndImageContext(); 图片截屏

/**
* 懒加载coverV
* 1.能够保证超始至终只有一份
* 2.什么时候用到什么时候才去加载
*/
-(UIView *)coverV {
if (_coverV == nil) {
//添加一个UIView
UIView *coverV = [[UIView alloc] init];
coverV.backgroundColor = [UIColor blackColor];
coverV.alpha = 0.7;
_coverV = coverV;
[self.view addSubview:coverV];
}
return _coverV;
}

- (void)viewDidLoad {
[super viewDidLoad];

self.imageV.userInteractionEnabled = YES;
}
- (IBAction)pan:(UIPanGestureRecognizer *)pan {
//判断手势的状态
CGPoint curP = [pan locationInView:self.imageV];
if(pan.state == UIGestureRecognizerStateBegan) {
self.startP = curP;
} else if(pan.state == UIGestureRecognizerStateChanged) {
CGFloat x = self.startP.x;
CGFloat y = self.startP.y;
CGFloat w = curP.x - self.startP.x;
CGFloat h = curP.y - self.startP.y;
CGRect rect = CGRectMake(x, y, w, h);
//添加一个UIView
self.coverV.frame = rect;
} else if (pan.state == UIGestureRecognizerStateEnded) {
//把超过coverV的frame以外的内容裁剪掉
//生成了一张图片,把原来的图片给替换掉.
UIGraphicsBeginImageContextWithOptions(self.imageV.bounds.size, NO, 0);
//把ImageV绘制到上下文之前,设置一个裁剪区域
UIBezierPath *clipPath = [UIBezierPath bezierPathWithRect:self.coverV.frame];
[clipPath addClip];

//把当前的ImageView渲染到上下文当中
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.imageV.layer renderInContext:ctx];
//.从上下文当中生成 一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
self.imageV.image = newImage;
}
}