UIImage的圆角 [英] Rounded Corners on UIImage

查看:124
本文介绍了UIImage的圆角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在iPhone上使用圆角绘制图像,在联系人应用程序中的联系人图片。我有代码一般工作,但它偶尔崩溃内部的UIImage绘图例程与 EXEC_BAD_ACCESS - KERN_INVALID_ADDRESS 。我认为这可能与裁剪问题有关,我几个星期后回答,但我相信我' m正确设置剪切路径。



这里是我使用的代码 - 当它不崩溃,结果看起来很好,任何人寻找类似的外观可以自由借用代码。

   - (UIImage *)borderedImageWithRect:(CGRect)dstRect radius:(CGFloat)radius {
UIImage * maskedImage = nil;

radius = MIN(radius,.5 * MIN(CGRectGetWidth(dstRect),CGRectGetHeight(dstRect)));
CGRect interiorRect = CGRectInset(dstRect,radius,radius);

UIGraphicsBeginImageContext(dstRect.size);
CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();
CGContextSaveGState(maskedContextRef);

CGMutablePathRef borderPath = CGPathCreateMutable();
CGPathAddArc(borderPath,NULL,CGRectGetMinX(interiorRect),CGRectGetMinY(interiorRect),radius,PNDegreeToRadian(180),PNDegreeToRadian(270),NO);
CGPathAddArc(borderPath,NULL,CGRectGetMaxX(interiorRect),CGRectGetMinY(interiorRect),radius,PNDegreeToRadian(270.0),PNDegreeToRadian(360.0),NO);
CGPathAddArc(borderPath,NULL,CGRectGetMaxX(interiorRect),CGRectGetMaxY(interiorRect),radius,PNDegreeToRadian(0.0),PNDegreeToRadian(90.0),NO);
CGPathAddArc(borderPath,NULL,CGRectGetMinX(interiorRect),CGRectGetMaxY(interiorRect),radius,PNDegreeToRadian(90.0),PNDegreeToRadian(180.0),NO);

CGContextBeginPath(maskedContextRef);
CGContextAddPath(maskedContextRef,borderPath);
CGContextClosePath(maskedContextRef);
CGContextClip(maskedContextRef);

[self drawInRect:dstRect];

maskedImage = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(maskedContextRef);
UIGraphicsEndImageContext();

return maskedImage;
}

这里是崩溃日志。

 
异常类型:EXC_BAD_ACCESS(SIGSEGV)
异常代码:KERN_INVALID_ADDRESS at 0x6e2e6181
崩溃的线程:0

线程0崩溃:
0 com.apple.CoreGraphics 0x30fe56d8 CGGStateGetRenderingIntent + 4
1 libRIP.A.dylib 0x33c4a7d8 ripc_RenderImage + 104
2 libRIP.A.dylib 0x33c51868 ripc_DrawImage + 3860
3 com.apple.CoreGraphics 0x30fecad4 CGContextDelegateDrawImage + 80
4 com.apple.CoreGraphics 0x30feca40 CGContextDrawImage + 368
5 UIKit 0x30a6a708 - [UIImage drawInRect:blendMode:alpha:] + 1460
6 UIKit 0x30a66904 - [UIImage drawInRect:] + 72
7 MyApp 0x0003f8a8 - [UIImage(PNAdditions)borderedImageWithRect:radius:](UIImage + PNAdditions.m:187 )


解决方案

这是一个更容易的方法,可用于iPhone 3.0及以上。每个基于视图的对象都有一个关联的图层。每一层都可以设置一个角半径,这将给你你想要的:

  UIImageView * roundedView = [[UIImageView alloc ] initWithImage:[UIImage imageNamed:@wood.jpg]]; 
//获取任意视图的图层
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];

//你甚至可以添加边框
[l setBorderWidth:4.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];


I'm trying to draw images on the iPhone using with rounded corners, a la the contact images in the Contacts app. I've got code that generally work, but it occasionally crashes inside of the UIImage drawing routines with an EXEC_BAD_ACCESS - KERN_INVALID_ADDRESS. I thought this might be related to the cropping question I asked a few weeks back, but I believe I'm setting up the clipping path correctly.

Here's the code I'm using - when it doesn't crash, the result looks fine and anybody looking to get a similar look is free to borrow the code.

- (UIImage *)borderedImageWithRect: (CGRect)dstRect radius:(CGFloat)radius {
    UIImage *maskedImage = nil;

    radius = MIN(radius, .5 * MIN(CGRectGetWidth(dstRect), CGRectGetHeight(dstRect)));
    CGRect interiorRect = CGRectInset(dstRect, radius, radius);

    UIGraphicsBeginImageContext(dstRect.size);
    CGContextRef maskedContextRef = UIGraphicsGetCurrentContext();
    CGContextSaveGState(maskedContextRef);

    CGMutablePathRef borderPath = CGPathCreateMutable();
    CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(180), PNDegreeToRadian(270), NO);
    CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMinY(interiorRect), radius, PNDegreeToRadian(270.0), PNDegreeToRadian(360.0), NO);
    CGPathAddArc(borderPath, NULL, CGRectGetMaxX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(0.0), PNDegreeToRadian(90.0), NO);
    CGPathAddArc(borderPath, NULL, CGRectGetMinX(interiorRect), CGRectGetMaxY(interiorRect), radius, PNDegreeToRadian(90.0), PNDegreeToRadian(180.0), NO);

    CGContextBeginPath(maskedContextRef);
    CGContextAddPath(maskedContextRef, borderPath);
    CGContextClosePath(maskedContextRef);
    CGContextClip(maskedContextRef);

    [self drawInRect: dstRect];

    maskedImage = UIGraphicsGetImageFromCurrentImageContext();
    CGContextRestoreGState(maskedContextRef);
    UIGraphicsEndImageContext();

    return maskedImage;
}

and here's the crash log. It looks the same whenever I get one of these crashes

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x6e2e6181
Crashed Thread:  0

Thread 0 Crashed:
0   com.apple.CoreGraphics          0x30fe56d8 CGGStateGetRenderingIntent + 4
1   libRIP.A.dylib                  0x33c4a7d8 ripc_RenderImage + 104
2   libRIP.A.dylib                  0x33c51868 ripc_DrawImage + 3860
3   com.apple.CoreGraphics          0x30fecad4 CGContextDelegateDrawImage + 80
4   com.apple.CoreGraphics          0x30feca40 CGContextDrawImage + 368
5   UIKit                           0x30a6a708 -[UIImage drawInRect:blendMode:alpha:] + 1460
6   UIKit                           0x30a66904 -[UIImage drawInRect:] + 72
7   MyApp                           0x0003f8a8 -[UIImage(PNAdditions) borderedImageWithRect:radius:] (UIImage+PNAdditions.m:187)

解决方案

Here is an even easier method that is available in iPhone 3.0 and up. Every View-based object has an associated layer. Each layer can have a corner radius set, this will give you just what you want:

UIImageView * roundedView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"wood.jpg"]];
// Get the Layer of any view
CALayer * l = [roundedView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];

// You can even add a border
[l setBorderWidth:4.0];
[l setBorderColor:[[UIColor blueColor] CGColor]];

这篇关于UIImage的圆角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆