YYWebImage图片处理 —— 圆角

作者: 天空中的球 | 来源:发表于2016-06-20 00:39 被阅读2174次

    在我们使用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图片处理 —— 圆角

        本文链接:https://www.haomeiwen.com/subject/fbjvdttx.html