开头
Quartz2D
实际用处
绘图
- C和OC都可以实现,也可以混合实现,下面只整理了oc的
//1.创建路径对象
UIBezierPath *path = [UIBezierPath bezierPath]
//2.通过路径对象拼接路径
[path moveToPoint:CGPointMake(50, 50)]
[path addLineToPoint:CGPointMake(100, 100)]
[path addLineToPoint:CGPointMake(200, 100)]
//3.渲染
[path stroke]
drawRect
- 这个方法当中可以获取到正确的上下文,代码要写到这个方法里
rect参数代表当前view的bounds
- 系统调用,当这个view第一次显示的时候会调用;当这个
view进行重绘的时候会调用
- 类型刷新,调用某个需要重绘的
view对象的setNeedsDisplay的方法,全部刷新;调用setNeedsDisplayInRect:(CGRect)rect,刷新指定区域
- 手动调用的时候获取不到正确的上下文
形状
//arccenter 圆心 radius 半径 startAngle 起始位置 endAngle 结束位置 clockwise 是否为顺时针
//0是三点钟方向,向下为正,顺时针到180度
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI clockwise:1]
[path stroke]
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 50, 200, 100)];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(100, 100, 100, 100) cornerRadius:5]
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 100, 100)]
NSArray *array = @[@0.3, @0.1, @0.2, @0.4]
CGFloat start = 0
CGFloat end = 0
for (int i = 0
end = 2 * M_PI * [array[i] floatValue] + start
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:start endAngle:end clockwise:1]
//扇形 往圆心连线
[path addLineToPoint:CGPointMake(150, 150)]
//随机颜色
[[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0] set]
[path fill]
//下一次的起点等于上一次的终点
start = end
}
NSArray *array = @[@1, @0.5, @0.7, @0.3, @0.1, @0.6]
//计算rect
for (int i = 0
CGFloat w = 20
CGFloat h = [array[i] floatValue] * rect.size.height
CGFloat x = i * 2 * w
CGFloat y = rect.size.height - h
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(x, y, w, h)]
[[UIColor colorWithRed:((float)arc4random_uniform(256) / 255.0) green:((float)arc4random_uniform(256) / 255.0) blue:((float)arc4random_uniform(256) / 255.0) alpha:1.0] set]
[path fill]
}
- (IBAction)progressChange:(UISlider *)sender {
self.progressView.progressValue = sender.value;
NSLog(@"%.2f", self.progressView.progressValue);
}
- (void)setProgressValue:(CGFloat)progressValue
{
_progressValue = progressValue
//如果有最新的数据,就直接重绘
[self setNeedsDisplay]
}
- (void)drawRect:(CGRect)rect {
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:- M_PI_2 endAngle:2 * M_PI * self.progressValue - M_PI_2 clockwise:1]
[path addLineToPoint:CGPointMake(150, 150)]
[[UIColor redColor] set]
[path fill]
}
样式
//线宽
[path setLineWidth:30]
//连接处
[path setLineJoinStyle:kCGLineJoinRound]
//头尾
[path setLineCapStyle:kCGLineCapRound]
//颜色
[[UIColor greenColor] setStroke]
渲染方式
UIBezierPath *path = [UIBezierPath new]
[path moveToPoint:CGPointMake(50, 50)]
[path addLineToPoint:CGPointMake(100, 100)]
[path addLineToPoint:CGPointMake(150, 50)]
//关闭路径,闭合
[path closePath]
[path setLineWidth:10]
[path setLineJoinStyle:kCGLineJoinRound]
//同时设置
[[UIColor redColor] set]
//即填充又描边同时打开
[[UIColor greenColor] setStroke]
[[UIColor redColor] setFill]
[path stroke]
[path fill]
- 奇偶填充
- 被覆盖过奇数次的点填充,被覆盖过偶数次的点不填充
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(100, 100, 200, 100)]
[path addArcWithCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:2 * M_PI clockwise:1]
path.usesEvenOddFillRule = YES
[path fill]
- 非零环绕熟
- 非零环绕数,默认填充规则 从左到右跨过 顺时针 +1 从右到左跨过 逆时针 -1 如果最后为0,那么不填充
CGContextRef ctx = UIGraphicsGetCurrentContext();
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:1];
UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:50 startAngle:0 endAngle:M_PI * 2 clockwise:0];
CGContextAddPath(ctx, path.CGPath);
CGContextAddPath(ctx, path1.CGPath);
CGContextDrawPath(ctx, kCGPathFill);
图文上下栈
- 保存样式
- 找离着最近的备份样式,类似{}打括号对应
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSaveGState(ctx);
CGContextAddArc(ctx, 150, 150, 100, 0, 2 * M_PI, 1);
CGContextMoveToPoint(ctx, 0, 0);
CGContextAddLineToPoint(ctx, 300, 300);
CGContextSetLineWidth(ctx, 10);
CGContextSaveGState(ctx);
[[UIColor redColor] set];
CGContextSaveGState(ctx);
CGContextMoveToPoint(ctx, 20, 20);
CGContextAddLineToPoint(ctx, 250, 20);
CGContextRestoreGState(ctx);
CGContextRestoreGState(ctx);
CGContextRestoreGState(ctx);
CGContextStrokePath(ctx);
绘制文字
NSString *str = @"test"
//绘制
//创建shadow
NSShadow *s = [NSShadow new]
s.shadowOffset = CGSizeMake(5, 0)
s.shadowBlurRadius = 2
s.shadowColor = [UIColor blackColor]
//固定起始点 NSFontAttributeName等
// NSBackgroundColorAttributeName:[UIColor greenColor]
//NSUnderlineStyleAttributeName:@(5) 下划线粗细
[str drawAtPoint:CGPointMake(50, 50) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20], NSForegroundColorAttributeName:[UIColor redColor], NSShadowAttributeName:s}]
//固定区域,左上角
[str drawInRect:rect withAttributes:nil]
绘制图片
UIImage *image = [UIImage imageNamed:@"1"];
[image drawAtPoint:CGPointMake(50, 50)];
[image drawInRect:rect];
[image drawAsPatternInRect:rect];
剪裁图片
UIImage *image = [UIImage imageNamed:@"Gin_1"];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddRect(ctx, CGRectMake(0, 0, 150, 150));
CGContextAddRect(ctx, CGRectMake(150, 150, 150, 150));
CGContextClip(ctx);
[image drawInRect:rect];
图形上下文
UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextMoveToPoint(ctx, 50, 50);
CGContextAddLineToPoint(ctx, 100, 100);
CGContextStrokePath(ctx);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
保存到沙盒中
NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *filePath = [docPath stringByAppendingPathComponent:@"test.png"];
NSLog(@"%@", filePath);
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:filePath atomically:YES];
保存图片到相册
Privacy - Photo Library Additions Usage Description
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UIImage *image = [UIImage imageNamed:@"papa"];
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextAddArc(ctx, image.size.width * 0.5, image.size.height * 0.5, image.size.width * 0.5, 0, 2 * M_PI, 1);
CGContextClip(ctx);
[image drawAtPoint:CGPointZero];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.imageView.image = newImage;
UIImageWriteToSavedPhotosAlbum(newImage, self, @selector(image: didFinishSavingWithError: contextInfo:), @"1231231231");
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
NSLog(@"保存完成 - %@", contextInfo);
}
带圆环的图片
//获取图片
UIImage *image = [UIImage imageNamed:@"papa"]
CGFloat margin = 20
//计算上下文大小
CGSize ctxSize = CGSizeMake(image.size.width + 2 * margin, image.size.height + 2 * margin)
//1.开启图片类型的图形上下文
UIGraphicsBeginImageContextWithOptions(ctxSize, NO, 0)
//2.计算圆心
CGPoint arcCenter = CGPointMake(ctxSize.width * 0.5, ctxSize.height * 0.5)
//3.计算半径
CGFloat radius = (image.size.width + margin) * 0.5
//4.获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext()
//5.画圆环
CGContextAddArc(ctx, arcCenter.x, arcCenter.y, radius, 0, 2 * M_PI, 1)
//6.设置宽度
CGContextSetLineWidth(ctx, margin)
//7.渲染圆环
CGContextStrokePath(ctx)
//8.画显示区域
CGContextAddArc(ctx, arcCenter.x, arcCenter.y, image.size.width * 0.5, 0, 2 * M_PI, 1)
//9.裁剪
CGContextClip(ctx)
//10.画图片
[image drawAtPoint:CGPointMake(margin, margin)]
image = UIGraphicsGetImageFromCurrentImageContext()
UIImageView *imageView = [[UIImageView alloc] init]
imageView.backgroundColor = [UIColor redColor]
imageView.image = image
imageView.frame = CGRectMake(100, 100, image.size.width, image.size.height)
[self.view addSubview:imageView]
//关闭
UIGraphicsEndImageContext()
添加水印
UIImage *image = [UIImage imageNamed:@"papa"]
//1.开启图片上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0)
//画大图
[image drawAtPoint:CGPointZero]
//图片水印
UIImage *logo = [UIImage imageNamed:@"99"]
[logo drawAtPoint:CGPointMake(image.size.width * 0.7, image.size.height * 0.7)]
//2.文字
NSString *str = @"test"
//3.画文字水印
[str drawAtPoint:CGPointMake(20, 20) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20]}]
//保存相册
image = UIGraphicsGetImageFromCurrentImageContext()
// UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL)
self.imageView.image = image
//关闭图形上下文
UIGraphicsEndImageContext()
屏幕截图
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:ctx];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, NULL, NULL, NULL);