Avatar在项目中用到的越来越多,我们应该如何去实现呢?
效果图1:
效果图2:
先从效果图1开始吧:
方法1:创建一个NSImage
,然后把图像绘制在圆圈里面
/ 根据我们ImageView的大小创建一个NSImage来保存绘制后的图像
NSImage *circleImage = [[NSImage alloc] initWithSize:self.imageView.frame.size];
// 告诉cocoa,我要用这个image开刀了,让他准备好接收绘图命令
[circleImage lockFocus];
// 画个圆
NSBezierPath *circlePath = [NSBezierPath bezierPathWithOvalInRect:NSMakeRect(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height)];
// 因为后面我们就要对当前的图形上下文做操作了,所以先保存当前的图形状态
[NSGraphicsContext saveGraphicsState];
// 把我们刚刚画的那个圆添加到截取区域中,作为绘图的区域
[circlePath addClip];
// 下面两段drawInRect的代码只用取一段就可以了
// 绘制目标图像,使用NSCompositeSourceOver作为合成选项
// 也就是绘制结果是源图片(刚刚我们画的那个圈的区域)不透明的叠加在我们的image上,这样结果就是image被一个圈圈罩住了,圈里面看得见,全外面没了
[image drawInRect:NSMakeRect(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height) fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1];
// 其实这里这样也可以,因为我们之前已经画了个圈作为截取区域了,那也就是说我们绘制的区域只有个圈了,不需要进行叠加也是可以的
[image drawInRect:NSMakeRect(0, 0, self.imageView.frame.size.width, self.imageView.frame.size.height)];
// 图形上下文操作结束,那么自然回复我们修改之前的图形上下文
[NSGraphicsContext restoreGraphicsState];
// 告诉cocoa我们画完了
[circleImage unlockFocus];
// 设置图片
self.imageView.image = circleImage;
PS: 要画在其他形状里面,只需要替换下上面代码中的circlePath,我们的路径是啥样的,这段代码就会把image画到啥样的形状里面;这里也说明了效果2实现的思路;
方法2:与上面类似
- (NSImage *)getRoundImageFromOriginalImage:(NSImage *)img preferredSize:(NSSize)size withAvatarType:(NSInteger)avatarType
{
if (!img)
return nil;
NSImage* newImage = [[[NSImage alloc] initWithSize:size] autorelease];
[newImage lockFocus];
CGFloat adjustment = 1.0;
//Draw outer line
NSRect outerRect = NSMakeRect(0 + adjustment, 0 + adjustment, size.width - 2 * adjustment, size.height - 2 * adjustment);
[self drawRoundBorderInRect:outerRect withLineWidth:[self outerLineWidth] andLineColor:[self getAvatarOuterLineColorForAvatarType:avatarType]];
//Draw avatar image
NSRect imageRect = NSMakeRect(outerRect.origin.x + [self outerLineWidth], outerRect.origin.y + [self outerLineWidth], outerRect.size.width - 2 * [self outerLineWidth], outerRect.size.height - 2 * [self outerLineWidth]);
NSBezierPath* bezierPath = [NSBezierPath bezierPathWithOvalInRect:imageRect];
[bezierPath addClip];
[img drawInRect:imageRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
//Draw inner line on top of the image
[self drawRoundBorderInRect:imageRect withLineWidth:[self innerLineWidth] andLineColor:[self getAvatarInnerLineColorForAvatarType:avatarType]];
[newImage unlockFocus];
return newImage;
}
- (void)drawRoundBorderInRect:(NSRect)rect withLineWidth:(CGFloat)width andLineColor:(NSColor *)color
{
NSBezierPath* roundPath = [NSBezierPath bezierPathWithOvalInRect:rect];
[color set];
[roundPath setLineWidth:width];
[roundPath stroke];
}
参考文档:http://noark9.github.io/2014/02/01/image-in-a-circle/