实现圆形图片的裁切有多种方法,可以直接设置layer.cornerRadius
,但这样会造成离屏渲染,耗费内存。在此不详述离屏渲染,想看的戳进去吧:iOS离屏渲染研究
先来个简单例子:实现圆形图片的裁切
- (UIImage *)circleImage:(UIImage *)image {
if (!image) return nil;
// 开始上下文,下面不使用时一定要关闭,从上下文栈中移除
UIGraphicsBeginImageContextWithOptions(image.size, NO
,[UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// 添加镶边
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColorWithColor(context, [UIColor yellowColor].CGColor);
//裁切
CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextAddEllipseInRect(context, rect);
CGContextClip(context);
// 在圆区内画出image原图
[image drawInRect:rect];
// 围绕当前路径画一条线,镶边线,注意在调用strokePath之前必须先添加线,fillPath也一样要先添加线才可操作
CGContextAddEllipseInRect(context, rect);
CGContextStrokePath(context);
//从上下文环境中获取切好的图片
UIImage *newImg = UIGraphicsGetImageFromCurrentImageContext();
// 使用了beginImgacontext需要关闭上下文 并从上下文栈中移除
UIGraphicsEndImageContext();
return newImg;
}
调用方式如:
UIImage *image = [UIImage imageNamed:@"welcome.png"];
UIImageView *imagView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 30, 120, 120)];
imagView.image = [self circleImage:image];
[self.view addSubview:imagView];
一直对上下文操作视图感到好奇,这下便查看部分文档资料,简单翻译了下,如有不合理欢迎指正:
UIGraphicsGetCurrentContext()
返回:
当前的图形上下文
描述:
默认情况下当前的图形上下文为nil,首先调用到它的是drawRect:方法,
视图控件将一个有效的上下文压到一个栈中,使其成为当前上下文, 如果你不使用一个控件对象来进行绘画,
那么你便需要手动将一个有效的上下文压到栈中通过使用UIGraphicsPushContext函数
这个方法可能从你app的任何线程中调用。
UIGraphicsPushContext(ctx):
使一个特殊的上下文成为当前的上下文
描述: 你可以使用这个功能去保存之前的图形上下文状态,并且使一个上下文成为当前的上下文,
使用这个方法需要配对使用UIGraphicsPopContext方法 这个方法可能从你的app的任何线程中调用
UIGraphicsPopContext(ctx):
从上下文栈中移除当前的上下文,恢复使用之前的上下文
UIGraphicsBeginImageContext(size)
创建一个基于位图的图形上下文,并使之成为当前的上下文
parameters:
size: 新位图上下文的尺寸,这个代表了通过 UIGraphicsGetImageFromCurrentImageContext方法返回的图片的尺寸
描述:
这个方法相当于调用了UIGraphicsBeginImageContextWithOptions方法,
并且opaque参数设置为NO,并且一个scale参数为1.0 这个方法可能从你的app的任何线程中调用
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
创建一个基于位图的图形上下文同时附带有相应的选择
parameters:
size: 新的位图上下文的尺寸(以点来作为量算单位)。
这展现在在UIGraphicsGetImageFromCurrentImageContext函数返回的图片的尺寸。
为了得到位图的的像素尺寸,你必须以宽度和高度乘以scale参数。
opaque: 一个BOOL值的标志标志着位图是否为半透明。如果你知道位图是完全的不透明,
赋值YES去忽略掉alpha通道并且优化位图的存储空间。
赋值为NO意味着位图必须要包含alpha通道去掌握着部分的透明像素。
scale: 这个scale元素去应用到位图中,如果你将其设置为0.0f,
那么就会以系统设备屏幕尺寸的的scale作为标准。
讨论:
你可以使用这个方法去配置绘画环境提交到位图中。
这个位图是ARGB32-bit整型像素格式使用主byte次序。如果opaque参数设置为YES,
这个alpha通道被忽略并且被认为是完全不透明(kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrer32Host)。
不然每一个像素使用premultipledARGB格式(kCGImageAlphaPremultipledFirst | kCGBitmapByteOrder32Host).
这个环境同时使用了默认的UIKit视图的坐标系统,它的原点是在左上角,
正轴是原点向下及向右。这个提供到的scale因为同样应用到坐标系统及得到的结果图片。
这个绘画环境会被立刻push到图形上下文。
当 当前上下文是通过这个方法生成的,你便可以调用UIGraphicsGetImageFromCurrentImageContext
函数去取回基于当前上下文的图片对象。当你不再改正上下文你必须去调用UIGraphicsEndImageContext方法去清理位图绘画环境并且从上下文栈中移除。
你不应该使用UIGraphicsPopContext函数去从栈上移除上下文。
在大多数其他情况,这个图形上下文创建与其他一样,你可以改变上下文通过
push或pop其他图形上下文,你一样可以通过UIGraphicsGetCurrentContext函数。
这个函数可以被任何线程的app调用
UIGraphicsGetImageFromCurrentImageContext
返回一个基于当前位图上下文中的内容
Return Value:
一个图片对象包含当前图片上下文中的内容
讨论:
你只能在一个位图上下文为当前上下文时才能调用这个方法。
如果当前上下文为nil或者不是通过调用UIGraphicsBeginImageContext来调用的,那么这个函数便返回nil.
这个函数可以被app的任何线程调用。
UIGraphicsEndImageContext
从上下文栈顶部移除当前的位图上下文
注: 你可以使用这个方法来清理通过UIGraphicsBeginImageContext函数创建的上下文并且可以移除在栈顶部并基于位图的上下文。
如果当前上下文不是通过UIGraphicsBeginImageContext函数创建,那么这个方法什么都不会去做。