在我們使用YYWebImage的過(guò)程中,常常會(huì)用到對(duì)圖片的處理,其中圓角比較常用的,因此進(jìn)一步了解這個(gè)是很有必要的。
[image yy_imageByRoundCornerRadius:5];
圖片設(shè)置圓角
想想剛開(kāi)始的時(shí)候,直接的是用:
imageView.layer.masksToBounds = YES;
imageView.layer.cornerRadius = 10.0;
后來(lái)開(kāi)始我是使用貝塞爾曲線(xiàn)UIBezierPath和Core Graphics框架畫(huà)出一個(gè)圓角的
// 使用貝塞爾曲線(xiàn)UIBezierPath和Core Graphics框架畫(huà)出一個(gè)圓角
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];
后來(lái)也嘗試用過(guò)CAShapeLayer和貝塞爾曲線(xiàn)UIBezierPath畫(huà)圓角圖片
// 使用CAShapeLayer和貝塞爾曲線(xiàn)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];
然后再接著優(yōu)化,UIImage 進(jìn)行一個(gè)繼承
@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
此時(shí)再看看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;
}
總的說(shuō)來(lái)就是這邊是考慮相當(dāng)全面的,對(duì) corners、borderWidth、 borderColor、borderLineJoin 都進(jìn)行處理啦,另外對(duì)比了之前我個(gè)人沒(méi)使用的方法:
* CGContextScaleCTM(context, 1, -1); // 用于縮放圖像(傳值)
* CGContextTranslateCTM(context, 0, -rect.size.height); //用于平移圖像
由于Core Graphics默認(rèn)使用 LLO(左下角為原點(diǎn))的坐標(biāo)系統(tǒng)的,所以用讓 UIKit 適應(yīng) Core Graphics,則需要做上述處理。
- CGContextSaveGState(context); // 保存模式狀態(tài)
- CGContextDrawImage(context, rect, self.CGImage); // 將圖像繪制到指定的context
- CGContextRestoreGState(context); // 還原模式狀態(tài)
另外需要添加顏色的時(shí)候,當(dāng)然是直接劃線(xiàn)啦。
總之,其實(shí)這是對(duì)Graphics Context的初步使用,需要直白的了解更多的zhi,可去讀讀iOS中的圖形變換,同時(shí)我的UIBezierPath也可以順便看看,哈哈。