使用UIBezierPath异步剪辑UIImage

koh*_*Xun 3 asynchronous uiimage ios uibezierpath uigraphicscontext

我想在不使用QuartzCore的情况下为UIImageView添加圆角以避免UIScrollView中的性能问题,所以我解决了它:

    UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake(self.cornerRadius, self.cornerRadius)];
    [path addClip];

    UIGraphicsBeginImageContextWithOptions(rect.size, NO, [[UIScreen mainScreen] scale]);

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetBlendMode(UIGraphicsGetCurrentContext( ),kCGBlendModeClear); CGContextSetStrokeColorWithColor(context, [UIColor clearColor].CGColor);
    CGContextAddPath(context,path.CGPath);
    CGContextClip(context);
    CGContextClearRect(context,CGRectMake(0,0,width,height));

    [_image drawInRect:rect];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)

遗憾的是,在drawRect中调用,这需要一点处理时间,这会在UIScrollView中滚动时产生滞后.因此,我试图在dispatch_async的帮助下在一个单独的线程中处理它.这消除了滞后,一切都顺利进行.但现在我有另一个问题.我在调试器中收到许多无效的上下文消息,因为当线程异步启动图像处理时,GraphicsContext并不总是存在.有没有办法处理我的图像中的圆角而不会得到无效的上下文消息?请注意,我不想使用QuarzCore的cornerRadius或mask-functions.

Kur*_*vis 5

你做的工作超出了你的需要."无效上下文"消息是在调用[path addClip]之前调用引起的UIGraphicsBeginImageContextWithOptions().在UIBezierPath尝试访问线程的当前图形上下文,但你没有设置一个呢.

这是获得相同结果的更简单方法.请注意,您根本不需要使用CGContext.

UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);

UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect byRoundingCorners:UIRectCornerTopLeft|UIRectCornerTopRight cornerRadii:CGSizeMake(self.cornerRadius, self.cornerRadius)];
[path addClip];

[_image drawInRect:rect];

UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)