YYWebImage图片处理 —— 圆角

在我们使用YYWebImage的过程中,常常会用到对图片的处理,其中圆角比较常用的,因此进一步了解这个是很有必要的。

 [image yy_imageByRoundCornerRadius:5];

图片设置圆角

想想刚开始的时候,直接的是用:

imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 10.0;

后来开始我是使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角的

// 使用贝塞尔曲线UIBezierPath和Core Graphics框架画出一个圆角
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];
imageView.image =[ UIImage imageNamed:@"dog"];
UIGraphicsBeginImageContextWithOptions(imageView.frame.size, NO, 1.0);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                                cornerRadius:5];
[path addClip];
[imageView drawRect:imageView.bounds];
imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.view addSubview:imageView];

后来也尝试用过CAShapeLayer和贝塞尔曲线UIBezierPath画圆角图片

// 使用CAShapeLayer和贝塞尔曲线UIBezierPath
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];
imageView.image = [UIImage imageNamed:@"dog"];
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds
                                               byRoundingCorners:UIRectCornerAllCorners
                                                     cornerRadii:CGSizeMake(10, 1)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc]init];
maskLayer.frame = imageView.bounds;
maskLayer.path = maskPath.CGPath;
imageView.layer.mask = maskLayer;
[self.view addSubview:imageView];
    

然后再接着优化,UIImage 进行一个继承

@implementation UIImage (YSImage)

// 制作圆角
- (UIImage *)ys_imageByRoundCornerRadius:(CGFloat)cornerRadius {
    // 防止圆角半径小于0,或者大于宽/高中较小值的一半。
    if (cornerRadius < 0) {
        cornerRadius = 0;
    }
    else if (cornerRadius > MIN(self.size.width, self.size.height)) {
        cornerRadius = MIN(self.size.width, self.size.height) / 2;
    }
    CGRect imageFrame = CGRectMake(0, 0, self.size.width, self.size.height);
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    [[UIBezierPath bezierPathWithRoundedRect:imageFrame cornerRadius:cornerRadius] addClip];
    [self drawInRect:imageFrame];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

@end

此时再看看YYImage是怎样处理的呢?

- (UIImage *)yy_imageByRoundCornerRadius:(CGFloat)radius
                                 corners:(UIRectCorner)corners
                             borderWidth:(CGFloat)borderWidth
                             borderColor:(UIColor *)borderColor
                          borderLineJoin:(CGLineJoin)borderLineJoin {
    
    if (corners != UIRectCornerAllCorners) {
        UIRectCorner tmp = 0;
        if (corners & UIRectCornerTopLeft) tmp |= UIRectCornerBottomLeft;
        if (corners & UIRectCornerTopRight) tmp |= UIRectCornerBottomRight;
        if (corners & UIRectCornerBottomLeft) tmp |= UIRectCornerTopLeft;
        if (corners & UIRectCornerBottomRight) tmp |= UIRectCornerTopRight;
        corners = tmp;
    }
    
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextTranslateCTM(context, 0, -rect.size.height);
    
    CGFloat minSize = MIN(self.size.width, self.size.height);
    if (borderWidth < minSize / 2) {
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(radius, borderWidth)];
        [path closePath];
        
        CGContextSaveGState(context);
        [path addClip];
        CGContextDrawImage(context, rect, self.CGImage);
        CGContextRestoreGState(context);
    }
    
    if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) {
        CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale;
        CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset);
        CGFloat strokeRadius = radius > self.scale / 2 ? radius - self.scale / 2 : 0;
        UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, borderWidth)];
        [path closePath];
        
        path.lineWidth = borderWidth;
        path.lineJoinStyle = borderLineJoin;
        [borderColor setStroke];
        [path stroke];
    }
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

总的说来就是这边是考虑相当全面的,对 corners、borderWidth、 borderColor、borderLineJoin 都进行处理啦,另外对比了之前我个人没使用的方法:

*  CGContextScaleCTM(context, 1, -1);  // 用于缩放图像(传值)
*  CGContextTranslateCTM(context, 0, -rect.size.height); //用于平移图像

由于Core Graphics默认使用 LLO(左下角为原点)的坐标系统的,所以用让 UIKit 适应 Core Graphics,则需要做上述处理。

  • CGContextSaveGState(context); // 保存模式状态
  • CGContextDrawImage(context, rect, self.CGImage); // 将图像绘制到指定的context
  • CGContextRestoreGState(context); // 还原模式状态

另外需要添加颜色的时候,当然是直接划线啦。

总之,其实这是对Graphics Context的初步使用,需要直白的了解更多的zhi,可去读读iOS中的图形变换,同时我的UIBezierPath也可以顺便看看,哈哈。

你可能感兴趣的:(YYWebImage图片处理 —— 圆角)