iOS 自定义绘制内容

一、Layer上下文
当UIView第一次显示出来的时候,会调用view的drawRect方法,在drawRect方法中,可以获取和当前视图相关联的图形上下文,图形上下文中已经包含了决定绘制的输出目标,在UIView的drawRect方法中调用 UIGraphicsGetCurrentContext方法即可以获取到上下文(Layer上下文);
当view的frame发生改变的时候,drawRect会被自动调用;自定义view的背景颜色如果是default color的话,在drawRect方法中,会有缓存,可以手动调用CGContextClearRect方法清除;

1.画线

CGContextMoveToPoint(ctx, 10, 100);  // 起点
CGContextAddLineToPoint(ctx, 100, 100);  // 终点

线(绘制直线,实际上layer并没有直接渲染出来,而只是保存了绘制的信息)
CGContextMoveToPoint方法默认会给我们创建一个路径,之后的操作会把点添加到路径中;
2.绘制圆和圆弧

CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50));  // 画圆
CGContextAddArc(ctx, 50, 50, 50, 0, M_PI_2, 0);  // 画圆弧,前两个参数为圆心,接着的参数分别为半径,开始弧度,结束弧度,画圆弧方向(1逆时针,0顺时针)

3.绘制矩形

CGContextAddRect(ctx, CGRectMake(10, 10, 100, 100));  
// 绘制矩形,之后需要调用渲染方法(参见第7条);
CGContextStrokeRect(ctx, CGRectMake(10, 10, 100, 100));  
// 绘制矩形 | Fill,自动渲染,不需要手动调用渲染方法;
UIRectFill(CGRectMake(10, 10, 100, 100));  
// 通过OC的方法绘制实心四边形,该方法没有空心的方法;

4.绘制文字

dict[NSForegroundColorAttributeName] = [UIColor redColor];  // 文字颜色
dict[NSBackgroundColorAttributeName] = [UIColor redColor];  // 文字背景
dict[NSFontAttributeName] = [UIFont systemFontOfSize:14];  //  文字大小
[str drawAtPoint:CGPointMake(50, 50) withAttributes:dict]; 
// 绘制到指定点
[str drawInRect:CGRectMake(50, 50, 100, 100) withAttributes:nil]; 
// 将文字绘制到指定范围内,如果一行显示不完会自动换行,当文字超出范围后不再显示;

5.绘制图片

[image drawInRect:CGRectMake(50, 50, 100, 100)];  
// 利用drawInRect方法绘制图片渲染到layer,拉伸原有图片;
[image drawAtPoint:CGPointMake(50, 50)];  // 将图片绘制到指定位置;
[image drawAsPatternInRect:CGRectMake(0, 0, 200, 200)];  // 平铺原有图片;

6.设置绘图信息/样式
(1). 颜色

CGContextSetRGBStrokeColor(ctx, 1,0, 0, 0, 1,0);  // 设置绘图颜色
CGContextSetRGBFillColor(ctx, 1,0, 0, 0, 1,0);
[[UIColor redColor] setFill]; // 调用OC的方法设置绘图的填充颜色
[[UIColor redColor] setStroke];
[[UIColor redColor] set];  // 同时设置实心和空心

(2). 样式

CGContextSetLineWidth(ctx, 10);  // 设置线宽
CGContextSetLineCap(ctx, CGLineCap);  // 设置线的起点和终点的样式
CGContextSetLineJoin(ctx, CGLineJoin);  // 设置线的拐点样式
CGContextClosePath(ctx);  // 根据设置的线的点,关闭图形

7.渲染

CGContextStrokePath(ctx);  // 绘制图形(渲染到view上),绘制一条空心的线;
CGContextFillPath(ctx);  // 渲染图形(填充)

8.贝赛尔曲线
需要三个点坐标,分别是控制器,当前点,结束点;

CGContextMoveToPoint(ctx, currentX, currentX);  // 首先移动到当前点;
CGContextAddQuadCurveToPoint(ctx, controllerX, controllerY, endX, endY);  // controllerX|controllerY 是控制点位置,endX|endY是结束点位置;

9.绘制样式保存

CGContextSaveGState(ctx);  // 保存一份纯净的上下文,调用一次此方法会就会拷贝一个上下文到栈中;
CGContextRestoreGState(ctx);  // 还原开始保存的纯净的上下文

10.矩阵操作
设置矩阵操作必须放置到添加绘图信息之前;

CGContextRotateCTM(ctx ,angle);
CGContextScaleCTM(ctx, scaleX, scaleY);
CGContextTranslateCTM(ctx , 0, 250);

在上面的操作之后,再调用比如moveToPoint等方法;
11.Clip
指定范围也就是指定剪切的方法一定要在渲染范围之前调用;

CGContextAddEllipseInRect(ctx, CGRectMake(100, 100, 50, 50)); // 往上下文中添加一个圆形区域;
CGContextClip(ctx);  // 指定上下文中可以显示内容的范围;

以上操作之后再进行moveToPoint、addPoint…,再进行渲染;
补充:如果在剪切之前有绘制操作,则剪切前的内容将不会改变,而是原样显示;

CGContextClearRect(ctx, rect);  // 清空某个区域的内容
// C中的路径
CGMutablePathRef path = CGPathCreateMutable();  // 创建路径;
CGPathMoveToPoint(path, NULL, 10, 10);  // 设置起点;
CGPathAddLineToPoint(path, NULL, 100, 100);  // 移动到某一点;
CGContextAddPath(ctx, path);  // 添加path到上下文中;
CGContextStrokePath(ctx);  // 渲染;
CGPathAddEllipseInRect(path, NULL, CGRectMake(10, 10, 100, 100));  // 添加画圆的路径;

注意:
但凡通过quarzt2d中带有create/copy/retain方法创建出来的对象都必须手动释放,有两种方法;

CGPathRelease(path);  // 释放对象;
CFRelease(path);  // 释放对象2;

12.OC中的Path

UIBezierPath *path = [UIBezierPath bezierPath];  // 创建路径
[path moveToPoint:CGPointMake(20, 20)];  // 设置起点
[path addLineToPoint:CGPointMake(100, 100)];  // 移动到某一点
[path setLineCapStyle:kCGLineCapRound];  // 设置线的样式;
[path setLineWidth:10];  // 线宽;
[[UIColor redColor] set]; // 颜色;
[path stroke];  // 渲染

在stroke渲染之前,也可以调用C方法设置CGContextRef对象的样式,比如[color set];

二、图形上下文
1.创建bitmap上下文

UIGraphicsBeginImageContextWithOptions(CGSize size, Bool opaque, CGFloat scale);
// size:指定将来创建出来的bitmap大小
// opaque:YES:不透明,如果某区域没内容,则显示黑色;
// scale:缩放比例,0表示不缩放

创建出来的bitmap就对应一个UIImage
2.获取所创建的bitmap上下文

CGContextRef ctx = UIGraphicsGetCurrentContext();

3.绘图

CGContextAddEllipseInRect(ctx, CGRectMake(0, 0, 100, 100));

4.渲染

CGContextStrokePath(ctx);

5.获取生成的图片

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

6.保存图片
保存绘制好的图片到文件中,先将图片转换为二进制数据,然后再将图片写到文件中;

NSData *data = UIImageJPEGRepresentation(image, 1);  // jpeg
NSData *data = UIImagePNGRepresentation(image);  // png
[data writeToFile:@"path" atomically:YES];

添加水印用一中的方法draw文字,draw图片实现水印功能;

7.截图

UIGraphicsBeginImageContextWithOptions(cgsize, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();
[view.layer renderInContext:context];  // 将view的layer所渲染的内容渲染到当前的ContextRef中;
// 取得图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

保存图片到相册,回调方法不需自定义,直接实现系统推荐的回调方法;

UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
-(void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
}

8.切割图片

CGImageRef subimageRef= CGImageCreateWithImageInRect(image.CGImage, CGRectMake(0, 0, 640, 480));;
//
UIImage *subImage = [UIImage imageWithCGImage:subimageRef];
[UIImagePNGRepresentation(subImage) writeToFile:@“path”atomically:YES];

9.关闭图形上下文

UIGraphicsEndImageContext();  // 关闭图片上下文
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值