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))];
}

results matching ""

    No results matching ""