Quartz2D绘图
图形上下文(Graphics Context):是一个CGContextRef类型数据
图形上下文的作用:
- 保存绘图的信息,绘图的状态
- 决定绘制输出目标
- 相同一套绘图序列,指定不同的Graphics Context,就可以将相同的图片绘制到不同目标
Quartz2D提供了以下几种类型的Graphics Context:
- Bitmap Graphics Context
- PDF Graphics Context
- Window Graphics Context
- Layer Graphics Context
- Printer Graphics Context
如何利用Quartz2D绘制东西倒view上
- 新建一个类,继承自UIView
- 实现-drawRect:(CGRect)rect方法
在上述方法中执行以下操作
1.取得当前view相关联的图形上下文
2.绘制相应的图形内容
3.利用图形上下文将绘制内容渲染到view中
画直线
- (void)drawLine
{
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
//绘制起始点
[path moveToPoint:CGPointMake(200, 200)];
//画直线到终点
[path addLineToPoint:CGPointMake(100, 100)];
[path addLineToPoint:CGPointMake(100, 200)];
//设置笔触(线条)的粗细
CGContextSetLineWidth(ctx, 10);
//设置笔触的颜色
CGContextSetStrokeColorWithColor(ctx,[UIColor redColor].CGColor);
//设置线条连接点的样式(尖角,圆角,方角)
CGContextSetLineJoin(ctx, kCGLineJoinRound);
//将路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
//将上下文中的笔触信息渲染到View中(View的layer中)
CGContextStrokePath(ctx);
}
画曲线
- (void)drawCur
{
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建路径
UIBezierPath *path = [UIBezierPath bezierPath];
//绘制起始点
[path moveToPoint:CGPointMake(200, 100)];
//画曲线到终点并设置控制点
[path addQuadCurveToPoint:CGPointMake(100, 200) controlPoint:CGPointMake(250, 250)];
//设置笔触颜色 也可以是 [[UIColor blueColor] set],系统会自动判断为笔触还是填充指定颜色
[[UIColor blueColor] setStroke];
//将路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
//将上下文中的笔触信息渲染到View中(View的layer中)
CGContextStrokePath(ctx);
}
画矩形
- (void)drawRect
{
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
//设置填充颜色 也可以是 [[UIColor blueColor] set],系统会自动判断为笔触还是填充指定颜色
[[UIColor redColor] setFill];
//将路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
//将上下文中的填充信息渲染到View中(View的layer中)
CGContextFillPath(ctx);
//创建矩形
UIBezierPath *path1 = [UIBezierPath bezierPathWithRect:CGRectMake(50, 50, 200, 200)];
//设置笔触颜色 也可以是 [[UIColor blueColor] set],系统会自动判断为笔触还是填充指定颜色
[[UIColor yellowColor] setStroke];
//将路径添加到上下文
CGContextAddPath(ctx, path1.CGPath);
//将上下文中的笔触信息渲染到View中(View的layer中)
CGContextStrokePath(ctx);
}
画圆角矩形
- (void)drawRoundRect
{
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建圆角矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, 200, 200) cornerRadius:30];
//设置填充颜色
[[UIColor cyanColor] setFill];
//将路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
//将上下文中的填充信息渲染到View中(View的layer中)
CGContextFillPath(ctx);
}
画圆形
- (void)drawRound
{
//获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//创建圆角矩形,宽度和高度相等,再将圆角半径设为矩形宽度的一半
int rectWidth = 200;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(50, 50, rectWidth, rectWidth) cornerRadius:rectWidth * 0.5];
//设置填充颜色
[[UIColor purpleColor] setFill];
//将路径添加到上下文
CGContextAddPath(ctx, path.CGPath);
//将上下文中的填充信息渲染到View中(View的layer中)
CGContextFillPath(ctx);
}
画弧线
- (void)drawArc
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
[[UIColor yellowColor] set];
[path fill];
/**注意,path fill,path stroke就相当于已经内部完成了获取上下文,
添加路径到上下文以及渲染,并不是代表这样写可以不用获取上下文等操作
**/
}
画扇形
- (void)drawSector
{
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(150, 150) radius:100 startAngle:0 endAngle:M_PI_2 clockwise:YES];
[path addLineToPoint:CGPointMake(150, 150)];
[path closePath];
[[UIColor greenColor] set];
[path fill];
}
如果要反复执行绘图方法drawRect,只要在绘图的view中执行
[self setNeedsDisplay];
绘制饼状图
- (void)drawPieWithDatas:(NSArray*)datas
{
CGPoint center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
CGFloat radius = self.bounds.size.width * 0.5 - 20;
CGFloat startAngle = 0;
CGFloat endAngle = 0;
CGFloat currentAngle = 0;
for(NSNumber *num in datas)
{
startAngle = endAngle;
currentAngle = num.intValue / 100.0 * M_PI * 2;
endAngle = startAngle + currentAngle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
[path addLineToPoint:center];
[[self rndRgbColor] setFill];
[path fill];
}
}
- (UIColor *) rndRgbColor
{
CGFloat r = arc4random_uniform(256) / 255.0;
CGFloat g = arc4random_uniform(256) / 255.0;
CGFloat b = arc4random_uniform(256) / 255.0;
return [UIColor colorWithRed:r green:g blue:b alpha:1];
}
保存到上下文状态栈
CGContextSaveState(ctx);
从上下文状态栈中恢复
CGContextRestoreState(ctx);
上下文矩阵操作
//位移
CGContextTranslateCTM(ctx, 100, 100);
//旋转
CGContextRotateCTM(ctx, M_PI_4);
//缩放
CGContextScaleCTM(ctx, 1.5, 1.5);
擦除CGContextRef选定矩形区域
CGContextClearRect(ctx, CGRectMake(X, Y, W, H));
获得图片的上下文,绘制剪裁图片
- (UIImage*)clipRoundImageWithImage:(UIImage*) image
{
//根据原始图片获取图片的上下文
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0);
//创建一个圆形路径
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, image.size.width, image.size.height)];
//创建路径后并不是用于绘制到上下文,而是用于剪裁
[path addClip];
//剪裁区域内绘制图片,区域外的内容将不会被绘制
[image drawAtPoint:CGPointZero];
//用当前的上下文创建一张图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//返回裁剪好的图片
return newImage;
}
绘制一个带边框的剪裁图片
- (UIImage*)clipRoundImageWithImage:(UIImage*) image borderWith:(CGFloat) borderWidth color:(UIColor*) color
{
CGSize size = CGSizeMake(image.size.width + borderWidth * 2, image.size.height + borderWidth * 2);
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
UIBezierPath *borderPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, size.width, size.height)];
[color setFill];
[borderPath fill];
UIBezierPath *clipPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(borderWidth, borderWidth, image.size.width, image.size.height)];
[clipPath addClip];
[image drawAtPoint:CGPointMake(borderWidth, borderWidth)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndPDFContext();
return newImage;
}
截取屏幕生成图片并保存到本地
//开启图片的上下文
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0);
//把当前view绘制到上下文中,必须要使用渲染的方式
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.view.layer renderInContext:ctx];
//从上下文中生成一张图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndPDFContext();
//将图片转为二进制流NSData
NSData *data = UIImageJPEGRepresentation(image, 1);
//将二进制流写入文件保存
[data writeToFile:@"/Users/zhangfan/Desktop/image.jpg" atomically:YES];
一个ImageView中图片的剪裁实例,根据手指拖拽的区域裁剪原图片,将裁剪后的图片绘制到ImageView中
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@property (strong, nonatomic) UIView *clipView;
@property (assign, nonatomic) CGPoint startPoint;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
//懒加载创建剪裁区域的UIView
- (UIView *)clipView
{
if(_clipView == nil)
{
_clipView = [[UIView alloc]init];
_clipView.backgroundColor = [UIColor whiteColor];
_clipView.alpha = 0.5;
[self.view addSubview:_clipView];
}
return _clipView;
}
//添加一个拖拽事件
- (IBAction)selectArea:(UIPanGestureRecognizer*)pan
{
//定义一个手指移动的结束点
CGPoint endPoint = [pan locationInView:self.view];
if(pan.state == UIGestureRecognizerStateBegan)
{
//当手指按下的时候创建起始点
self.startPoint = endPoint;
}
else if(pan.state == UIGestureRecognizerStateChanged)
{
//当手指移动的时候,计算拖动的矩形区域
CGRect rect = CGRectMake(self.startPoint.x, self.startPoint.y, endPoint.x - self.startPoint.x, endPoint.y - self.startPoint.y);
self.clipView.frame = rect;
}
else if(pan.state == UIGestureRecognizerStateEnded)
{
//当手指松开的时候,绘制剪裁的图片
//开启上下文 UIGraphicsBeginImageContextWithOptions(self.imageView.bounds.size, NO, 0);
//创建一个矩形路径
UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.clipView.frame];
//将路径设为剪裁区域
[path addClip];
//创建一个上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
//将imageView渲染到上下文中
[self.imageView.layer renderInContext:ctx];
//定义一个新的UIImage从上下文中取出图片
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//将新的image赋值给self.imageView
self.imageView.image = newImage;
//清除拖拽区域效果
[self.clipView removeFromSuperview];
self.clipView = nil;
}
}
@end
将一个大图片裁剪成若干小份的方法
for(int i = 0; i < 12; i++)
{
UIImage *clipedImage = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(astrologyImage.CGImage, CGRectMake(X, Y, W, H))];
}