iOS - Quartz 2D 画板绘制

简介: 1、绘制画板1.1 绘制简单画板PaintBoardView.h @interface PaintBoardView : UIView @endPaintBoardView.

1、绘制画板

1.1 绘制简单画板

  • PaintBoardView.h

        @interface PaintBoardView : UIView
    
        @end
  • PaintBoardView.m

        @interface PaintBoardView ()
    
        /// 路径
        @property (nonatomic, strong) UIBezierPath *path;
    
        /// 保存所有路径的数组
        @property (nonatomic, strong) NSMutableArray *pathsArrayM;
    
        @end
    
        @implementation PaintBoardView
    
        /// 初始化
        - (instancetype)initWithFrame:(CGRect)frame {
    
            if (self = [super initWithFrame:frame]) {
                self.backgroundColor = [UIColor whiteColor];
            }
            return self;
        }
    
        /// 触摸开始
        - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            // 获取触摸起始点位置
            CGPoint startPoint = [touches.anyObject locationInView:self];
    
            // 添加路径描绘起始点
            [self.path moveToPoint:startPoint];
    
            // 添加一条触摸路径描绘
            [self.pathsArrayM addObject:self.path];
        }
    
        /// 触摸移动
        - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            // 获取触摸点位置
            CGPoint touchPoint = [touches.anyObject locationInView:self];
    
            // 添加路径描绘
            [self.path addLineToPoint:touchPoint];
    
            // 刷新视图
            [self setNeedsDisplay];
        }
    
        /// 触摸结束
        - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            // 获取绘制结果
            UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
            CGContextRef ctx = UIGraphicsGetCurrentContext();
            [self.layer renderInContext:ctx];
            UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
            UIGraphicsEndImageContext();
    
            NSData *data = UIImagePNGRepresentation(image);
            [data writeToFile:@"/Users/JHQ0228/Desktop/Images/pic.png" atomically:YES];
        }
    
        /// 触摸取消
        - (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event {
            [self touchesEnded:touches withEvent:event];
        }
    
        /// 绘制图形
        - (void)drawRect:(CGRect)rect {
    
            for (UIBezierPath *path in self.pathsArrayM) {
    
                // 绘制路径
                [path stroke];
            }
        }
    
        /// 懒加载
    
        - (UIBezierPath *)path {
    
            if (_path == nil) {
                _path = [UIBezierPath bezierPath];
            }
            return _path;
        }
    
        - (NSMutableArray *)pathsArrayM {
    
            if (_pathsArrayM == nil) {
                _pathsArrayM = [NSMutableArray array];
            }
            return _pathsArrayM;
        }
    
        @end
  • ViewController.m

        // 创建画板
        CGRect frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 200);
        PaintBoardView *paintBoard = [[PaintBoardView alloc] initWithFrame:frame];
    
        [self.view addSubview:paintBoard];
  • 效果

    Quartz2D102Quartz2D103

1.2 绘制画板封装

  • 具体实现代码见 GitHub 源码 QExtension

  • QPaintBoardPath.h

        @interface QPaintBoardPath : UIBezierPath
    
        /// 线的颜色
        @property (nonatomic, strong) UIColor *pathColor;
    
        /// 线的宽度
        @property (nonatomic, assign) CGFloat pathWidth;
    
        @end
  • QPaintBoardPath.m

        @implementation QPaintBoardPath
    
        @end
  • QPaintBoardView.h

        @interface QPaintBoardView : UIView
    
        /// 画线的宽度,default is 1,max is 30
        @property (nonatomic, assign) CGFloat paintLineWidth;
    
        /// 画笔的颜色,default is blackColor
        @property (nonatomic, strong) UIColor *paintLineColor;
    
        /// 画板的颜色,default is whiteColor
        @property (nonatomic, strong) UIColor *paintBoardColor;
    
        /**
         *  创建画板视图控件,获取绘画结果
         *
         *  @param frame        画板视图控件 frame
         *  @param lineWidth    画笔的线宽,default is 1,max is 30
         *  @param lineColor    画笔的颜色,default is blackColor
         *  @param boardColor   画板的颜色,default is whiteColor
         *  @param result       绘画结果
         *
         *  @return 手势锁视图控件
         */
        + (instancetype)q_paintBoardViewWithFrame:(CGRect)frame
                                        lineWidth:(CGFloat)lineWidth
                                        lineColor:(nullable UIColor *)lineColor
                                       boardColor:(nullable UIColor *)boardColor
                                      paintResult:(void (^)(UIImage * _Nullable image))result;
    
        /**
         *  创建简单画板视图控件
         *
         *  @param frame    画板视图控件 frame
         *
         *  @return 手势锁视图控件
         */
        + (instancetype)q_paintBoardViewWithFrame:(CGRect)frame;
    
        /**
         *  获取绘画结果
         *
         *  @return 绘画结果图片
         */
        - (UIImage * _Nullable)q_getPaintImage;
    
        /**
         *  清除绘画结果
         */
        - (void)q_clear;
    
        /**
         *  撤销绘画结果
         */
        - (void)q_back;
    
        @end
  • QPaintBoardView.m

        #import "QPaintBoardPath.h"
    
        @interface QPaintBoardView ()
    
        /// 路径
        @property (nonatomic, strong, nullable) QPaintBoardPath *path;
    
        /// 保存所有路径的数组
        @property (nonatomic, strong) NSMutableArray *pathsArrayM;
    
        /// 绘画结果
        @property (nonatomic, copy) void (^resultBlock)(UIImage * _Nullable);
    
        /// 按钮工具条
        @property (nonatomic, strong) UIView *toolView;
    
        /// 画笔设置视图
        @property (nonatomic, strong) UIView *brushSetingView;
    
        /// 颜色选择视图
        @property (nonatomic, strong) UIScrollView *colorSelectedView;
    
        /// 画板设置视图
        @property (nonatomic, strong) UIScrollView *boardSetingView;
    
        /// 记录线的颜色
        @property (nonatomic, strong) UIColor *lastPaintLineColor;
    
        /// 记录线的宽度
        @property (nonatomic, assign) CGFloat lastPaintLineWidth;
    
        @end
    
        @implementation QPaintBoardView
    
        #pragma mark - 创建画板
    
        /// 创建画板视图控件,获取绘画结果
        + (instancetype)q_paintBoardViewWithFrame:(CGRect)frame
                                        lineWidth:(CGFloat)lineWidth
                                        lineColor:(nullable UIColor *)lineColor
                                       boardColor:(nullable UIColor *)boardColor
                                      paintResult:(void (^)(UIImage * _Nullable image))result {
    
            QPaintBoardView *paintBoardView = [[self alloc] init];
    
        //    CGRect tmpFrame = frame;
        //    tmpFrame.size.height = frame.size.height + 44;
    
            paintBoardView.frame = frame;
            paintBoardView.paintLineWidth = (lineWidth > 30 ? 30 : lineWidth) ? : 1;
            paintBoardView.paintLineColor = lineColor ? : [UIColor blackColor];
            paintBoardView.paintBoardColor = boardColor ? : [UIColor whiteColor];
            paintBoardView.resultBlock = result;
    
            return paintBoardView;
        }
    
        /// 创建简单画板视图控件
        + (instancetype)q_paintBoardViewWithFrame:(CGRect)frame {
    
            QPaintBoardView *paintBoardView = [[self alloc] initWithFrame:frame];
    
            paintBoardView.paintLineWidth = 1;
            paintBoardView.paintLineColor = [UIColor blackColor];
            paintBoardView.paintBoardColor = [UIColor whiteColor];
    
            return paintBoardView;
        }
    
        #pragma mark - 自定义画板
    
        /// 初始化,自定义画板界面
        - (instancetype)init {
    
            if (self = [super init]) {
    
                self.clipsToBounds = YES;
    
                // 添加工具按钮视图
    
                self.toolView = [[UIView alloc] init];
                self.toolView.backgroundColor = [UIColor blackColor];
                [self addSubview:self.toolView];
    
                NSArray *imageNames = @[@"btn_brush", @"btn_board", @"btn_eraser", @"btn_back", @"btn_clear", @"btn_save"];
                NSArray *selectedImageNames = @[@"btn_brush_pressed", @"btn_board_pressed", @"btn_eraser_pressed"];
    
                for (NSUInteger i = 0; i < 6; i++) {
    
                    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
                    button.tag = i;
                    [button setBackgroundImage:[self q_getBundleImageWithName:imageNames[i]] forState:UIControlStateNormal];
                    [button addTarget:self action:@selector(toolButtonClick:) forControlEvents:UIControlEventTouchUpInside];
                    [self.toolView addSubview:button];
    
                    if (i < 3) {
                        [button setBackgroundImage:[self q_getBundleImageWithName:selectedImageNames[i]] forState:UIControlStateSelected];
                    }
                }
    
                // 添加画笔设置视图
    
                self.brushSetingView = [[UIView alloc] init];
                self.brushSetingView.backgroundColor = [UIColor grayColor];
                [self addSubview:self.brushSetingView];
                [self sendSubviewToBack:self.brushSetingView];
    
                UIView *widthBackView = [[UIView alloc] init];
                widthBackView.layer.borderWidth = 1;
                widthBackView.layer.borderColor = [UIColor lightGrayColor].CGColor;
                UIView *widthView = [[UIView alloc] init];
                [widthBackView addSubview:widthView];
                [self.brushSetingView addSubview:widthBackView];
    
                UISlider *widthSlider = [[UISlider alloc] init];
                widthSlider.thumbTintColor = [UIColor orangeColor];
                [widthSlider addTarget:self action:@selector(widthSliderClick:) forControlEvents:UIControlEventValueChanged];
                [self.brushSetingView addSubview:widthSlider];
    
                UIButton *colorSelectedBtn = [[UIButton alloc] init];
                colorSelectedBtn.layer.borderWidth = 1;
                colorSelectedBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
                [colorSelectedBtn addTarget:self action:@selector(colorSelectedBtnClick:) forControlEvents:UIControlEventTouchUpInside];
                [self.brushSetingView addSubview:colorSelectedBtn];
    
                // 添加画笔颜色选择视图
    
                self.colorSelectedView = [[UIScrollView alloc] init];
                self.colorSelectedView.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.3];
                self.colorSelectedView.showsHorizontalScrollIndicator = NO;
                [self addSubview:self.colorSelectedView];
                [self sendSubviewToBack:self.colorSelectedView];
    
                NSArray *colorArray = @[[UIColor blackColor], [UIColor whiteColor], [UIColor redColor],
                                        [UIColor greenColor], [UIColor blueColor], [UIColor cyanColor],
                                        [UIColor magentaColor], [UIColor orangeColor], [UIColor yellowColor],
                                        [UIColor darkGrayColor], [UIColor lightGrayColor], [UIColor brownColor],
                                        [UIColor grayColor], [UIColor purpleColor]];
    
                for (NSUInteger i = 0; i < 14; i++) {
                    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
                    button.layer.borderWidth = 1;
                    button.layer.borderColor = [UIColor lightGrayColor].CGColor;
                    [button setBackgroundColor:colorArray[i]];
                    [button addTarget:self action:@selector(colorSelectedClick:) forControlEvents:UIControlEventTouchUpInside];
                    [self.colorSelectedView addSubview:button];
                }
    
                // 添加画板设置视图
    
                self.boardSetingView = [[UIScrollView alloc] init];
                self.boardSetingView.backgroundColor = [UIColor grayColor];
                self.boardSetingView.showsHorizontalScrollIndicator = NO;
                [self addSubview:self.boardSetingView];
                [self sendSubviewToBack:self.boardSetingView];
    
                for (NSUInteger i = 0; i < 14; i++) {
                    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
                    button.layer.borderWidth = 1;
                    button.layer.borderColor = [UIColor lightGrayColor].CGColor;
                    [button setBackgroundColor:colorArray[i]];
                    [button addTarget:self action:@selector(boardColorSelectedClick:) forControlEvents:UIControlEventTouchUpInside];
                    [self.boardSetingView addSubview:button];
                }
            }
            return self;
        }
    
        /// 布局子控件
        - (void)layoutSubviews {
            [super layoutSubviews];
    
            if (self.subviews.count) {
    
                // 设置工具按钮视图
    
                self.toolView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 44);
    
                for (NSUInteger i = 0; i < 6; i++) {
                    CGFloat margin = (self.bounds.size.width - 44 * 6) / 7;
                    CGFloat x = margin + (margin + 44) * i;
                    self.toolView.subviews[i].frame = CGRectMake(x, 0, 44, 44);
                }
    
                // 设置画笔设置视图
    
                self.brushSetingView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
    
                self.brushSetingView.subviews[0].frame = CGRectMake(15, 15, 30, 30);
                self.brushSetingView.subviews[0].layer.cornerRadius = 15;
                self.brushSetingView.subviews[0].layer.masksToBounds = YES;
    
                CGFloat w = self.paintLineWidth;
                self.brushSetingView.subviews[0].subviews[0].frame = CGRectMake(15 - w / 2, 15 - w / 2, w, w);
                self.brushSetingView.subviews[0].subviews[0].layer.cornerRadius = w / 2;
                self.brushSetingView.subviews[0].subviews[0].layer.masksToBounds = YES;
                self.brushSetingView.subviews[0].subviews[0].backgroundColor = self.paintLineColor;
    
                self.brushSetingView.subviews[1].frame = CGRectMake(60, 15, self.bounds.size.width - 60 - 80, 32);
                UISlider *slider = self.brushSetingView.subviews[1];
                slider.value = self.paintLineWidth / 30;
    
                self.brushSetingView.subviews[2].frame = CGRectMake(self.bounds.size.width - 60, 15, 50, 30);
                self.brushSetingView.subviews[2].backgroundColor = self.paintLineColor;
    
                // 设置画笔颜色选择视图
    
                self.colorSelectedView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
                self.colorSelectedView.contentSize = CGSizeMake(14 * (50 + 20) + 20, 50);
    
                for (NSUInteger i = 0; i < 14; i++) {
                    CGFloat x = 20 + (20 + 50) * i;
                    self.colorSelectedView.subviews[i].frame = CGRectMake(x, 10, 50, 40);
                }
    
                // 设置画板设置视图
    
                self.boardSetingView.frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
                self.boardSetingView.contentSize = CGSizeMake(14 * (50 + 20) + 20, 50);
    
                for (NSUInteger i = 0; i < 14; i++) {
                    CGFloat x = 20 + (20 + 50) * i;
                    self.boardSetingView.subviews[i].frame = CGRectMake(x, 10, 50, 40);
                }
            }
        }
    
        /// 工具按钮点击事件处理
        - (void)toolButtonClick:(UIButton *)btn {
    
            switch (btn.tag) {
    
                case 0: {
                    // 画笔设置
    
                    [self exitEraseState];
    
                    if (btn.isSelected == NO) {
    
                        [self hideBoardSetingView];
    
                        [self showColorSelectedView];
                        [self showBrushSetingView];
    
                    } else {
    
                        [self hideColorSelectedView];
                        [self hideBrushSetingView];
                    }
                    break;
                }
    
                case 1: {
                    // 画板设置
    
                    [self exitEraseState];
    
                    if (btn.isSelected == NO) {
    
                        [self hideColorSelectedView];
                        [self hideBrushSetingView];
    
                        [self showBoardSetingView];
    
                    } else {
    
                        [self hideBoardSetingView];
                    }
                    break;
                }
    
                case 2: {
                    // 擦除
    
                    [self hideBoardSetingView];
    
                    [self hideColorSelectedView];
                    [self hideBrushSetingView];
    
                    if (btn.selected == NO) {
    
                        [self enterEraseState];
    
                    } else {
                        [self exitEraseState];
                    }
                    break;
                }
    
                case 3: {
                    // 撤销
    
                    [self hideBoardSetingView];
    
                    [self hideColorSelectedView];
                    [self hideBrushSetingView];
    
                    [self q_back];
    
                    break;
                }
    
                case 4: {
                    // 清除
    
                    [self hideBoardSetingView];
    
                    [self hideColorSelectedView];
                    [self hideBrushSetingView];
    
                    [self exitEraseState];
    
                    [self q_clear];
    
                    break;
                }
    
                case 5: {
                    // 获取绘制结果
    
                    [self hideBoardSetingView];
    
                    [self hideColorSelectedView];
                    [self hideBrushSetingView];
    
                    [self exitEraseState];
    
                    if (self.resultBlock) {
                        self.resultBlock([self q_getPaintImage]);
                    }
    
                    break;
                }
    
                default:
                    break;
            }
        }
    
        /// 画笔线宽设置按钮点击事件处理
        - (void)widthSliderClick:(UISlider *)slider {
    
            if (slider.value == 0) {
                self.paintLineWidth = 1;
            } else {
                self.paintLineWidth = slider.value * 30;
            }
    
            CGFloat w = self.paintLineWidth;
            self.brushSetingView.subviews[0].subviews[0].frame = CGRectMake(15 - w / 2, 15 - w / 2, w, w);
            self.brushSetingView.subviews[0].subviews[0].layer.cornerRadius = w / 2;
        }
    
        /// 画笔颜色选择按钮点击事件处理
        - (void)colorSelectedBtnClick:(UIButton *)btn {
    
            if (btn.selected == NO) {
                [self showColorSelectedView];
            } else {
                [self hideColorSelectedView];
            }
        }
    
        /// 画笔颜色选择点击响应事件处理
        - (void)colorSelectedClick:(UIButton *)btn {
    
            self.paintLineColor = btn.backgroundColor;
    
            self.brushSetingView.subviews[0].subviews[0].backgroundColor = btn.backgroundColor;
            self.brushSetingView.subviews[2].backgroundColor = btn.backgroundColor;
        }
    
        /// 画板颜色选择点击响应事件处理
        - (void)boardColorSelectedClick:(UIButton *)btn {
    
            self.paintBoardColor = btn.backgroundColor;
        }
    
        /// 显示画笔设置视图
        - (void)showBrushSetingView {
    
            UIButton *setBrushBtn = self.toolView.subviews[0];
    
            if (setBrushBtn.selected == NO) {
    
                setBrushBtn.selected = YES;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60, self.bounds.size.width, 60);
                    self.brushSetingView.frame = frame;
                }];
            }
        }
    
        /// 隐藏画笔设置视图
        - (void)hideBrushSetingView {
    
            UIButton *setBrushBtn = self.toolView.subviews[0];
    
            if (setBrushBtn.selected) {
    
                setBrushBtn.selected = NO;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
                    self.brushSetingView.frame = frame;
                }];
            }
        }
    
        // 显示画笔颜色选择视图
        - (void)showColorSelectedView {
    
            UIButton *colorSelectedBtn = self.brushSetingView.subviews[2];
    
            if (colorSelectedBtn.selected == NO) {
    
                colorSelectedBtn.selected = YES;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60 - 60, self.bounds.size.width, 60);
                    self.colorSelectedView.frame = frame;
                }];
            }
        }
    
        /// 隐藏画笔颜色选择视图
        - (void)hideColorSelectedView {
    
            UIButton *colorSelectedBtn = self.brushSetingView.subviews[2];
    
            if (colorSelectedBtn.selected) {
    
                colorSelectedBtn.selected = NO;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
                    self.colorSelectedView.frame = frame;
                }];
            }
        }
    
        /// 显示画板设置视图
        - (void)showBoardSetingView {
    
            UIButton *setBoardBtn = self.toolView.subviews[1];
    
            if (setBoardBtn.selected == NO) {
    
                setBoardBtn.selected = YES;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44 - 60, self.bounds.size.width, 60);
                    self.boardSetingView.frame = frame;
                }];
            }
        }
    
        /// 隐藏画板设置视图
        - (void)hideBoardSetingView {
    
            UIButton *setBoardBtn = self.toolView.subviews[1];
    
            if (setBoardBtn.selected) {
    
                setBoardBtn.selected = NO;
    
                [UIView animateWithDuration:0.2 animations:^{
                    CGRect frame = CGRectMake(0, self.bounds.size.height - 44, self.bounds.size.width, 60);
                    self.boardSetingView.frame = frame;
                }];
            }
        }
    
        /// 进入擦除状态
        - (void)enterEraseState {
    
            UIButton *setEraseBtn = self.toolView.subviews[2];
    
            if (setEraseBtn.selected == NO) {
    
                setEraseBtn.selected = YES;
    
                self.lastPaintLineColor = self.paintLineColor;
                self.paintLineColor = self.paintBoardColor;
    
                self.lastPaintLineWidth = self.paintLineWidth;
                self.paintLineWidth = self.paintLineWidth + 5;
            }
        }
    
        /// 退出擦除状态
        - (void)exitEraseState {
    
            UIButton *setEraseBtn = self.toolView.subviews[2];
    
            if (setEraseBtn.isSelected) {
    
                setEraseBtn.selected = NO;
    
                self.paintLineColor = self.lastPaintLineColor;
                self.paintLineWidth = self.lastPaintLineWidth;
            }
        }
    
        #pragma mark - 绘制图案
    
        /// 触摸开始
        - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            if (self.subviews.count) {
    
                [self hideColorSelectedView];
                [self hideBrushSetingView];
                [self hideBoardSetingView];
            }
    
            // 获取触摸起始点位置
            CGPoint startPoint = [touches.anyObject locationInView:self];
    
            // 添加路径描绘起始点
            [self.path moveToPoint:startPoint];
    
            // 记录线的属性
            self.path.pathColor = self.paintLineColor;
            self.path.pathWidth = self.paintLineWidth;
    
            // 添加一条触摸路径描绘
            [self.pathsArrayM addObject:self.path];
        }
    
        /// 触摸移动
        - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            // 获取触摸点位置
            CGPoint touchPoint = [touches.anyObject locationInView:self];
    
            // 添加路径描绘
            [self.path addLineToPoint:touchPoint];
    
            // 刷新视图
            [self setNeedsDisplay];
        }
    
        /// 触摸结束
        - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event {
    
            // 销毁 path
            self.path = nil;
        }
    
        /// 触摸取消
        - (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event {
            [self touchesEnded:touches withEvent:event];
        }
    
        /// 绘制图形,只要调用 drawRect 方法就会把之前的内容全部清空
        - (void)drawRect:(CGRect)rect {
    
            for (QPaintBoardPath *path in self.pathsArrayM) {
    
                // 绘制路径
                path.lineWidth = path.pathWidth;
                [path.pathColor setStroke];
    
                path.lineCapStyle = kCGLineCapRound;
                path.lineJoinStyle = kCGLineJoinRound;
                [path stroke];
            }
        }
    
        /// 获取绘画结果
        - (UIImage * _Nullable)q_getPaintImage {
    
            UIImage *image = nil;
    
            CGSize boardSize = self.bounds.size;
    
            if (self.subviews.count) {
                boardSize.height = self.bounds.size.height - 44;
            }
    
            if (self.pathsArrayM.count) {
                UIGraphicsBeginImageContextWithOptions(boardSize, NO, 0);
                CGContextRef ctx = UIGraphicsGetCurrentContext();
                [self.layer renderInContext:ctx];
                image = UIGraphicsGetImageFromCurrentImageContext();
                UIGraphicsEndImageContext();
            }
    
            return image;
        }
    
        /// 清除绘画结果
        - (void)q_clear {
    
            if (self.pathsArrayM.count) {
                [self.pathsArrayM removeAllObjects];
    
                [self setNeedsDisplay];
            }
        }
    
        /// 撤销绘画结果
        - (void)q_back {
    
            if (self.pathsArrayM.count) {
                [self.pathsArrayM removeLastObject];
    
                [self setNeedsDisplay];
            }
        }
    
        /// 懒加载
    
        - (QPaintBoardPath * _Nullable)path {
    
            // path 每次绘制完成后需要销毁,否则无法清除之前绘制的路径
    
            if (_path == nil) {
                _path = [QPaintBoardPath bezierPath];
            }
            return _path;
        }
    
        - (NSMutableArray *)pathsArrayM {
    
            if (_pathsArrayM == nil) {
                _pathsArrayM = [NSMutableArray array];
            }
            return _pathsArrayM;
        }
    
        /// 设置属性值
        - (void)setPaintBoardColor:(UIColor *)paintBoardColor {
            _paintBoardColor = paintBoardColor;
            self.backgroundColor = paintBoardColor;
        }
    
        /// 加载 bundle 中的图片
        - (UIImage *)q_getBundleImageWithName:(NSString *)name {
    
            NSString *bundlePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"QPaintBoardView.bundle"];
    
            UIImage *image = [[UIImage imageWithContentsOfFile:[bundlePath stringByAppendingPathComponent:name]]
                              imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
            return image;
        }
    
        @end
  • 1、创建简单画板

        // 创建简单画板
        CGRect frame = CGRectMake(20, 50, self.view.bounds.size.width - 40, 200);
    
        QPaintBoardView *paintBoardView = [QPaintBoardView q_paintBoardViewWithFrame:frame];
    
        // 可选属性值设置
        paintBoardView.paintLineWidth = 5;                         // default is 1
        paintBoardView.paintLineColor = [UIColor redColor];        // default is blackColor
        paintBoardView.paintBoardColor = [UIColor cyanColor];      // default is whiteColor
    
        [self.view addSubview:paintBoardView];
        self.paintBoardView = paintBoardView;
    
        // 撤销绘画结果
        [self.paintBoardView q_back];
    
        // 清除绘画结果
        [self.paintBoardView q_clear];
    
        // 获取绘画结果
        UIImage *image = [self.paintBoardView q_getPaintImage];
    • 效果

      Quartz2D104Quartz2D105

  • 2、创建画板

        // 创建画板
        QPaintBoardView *paintBoard = [QPaintBoardView q_paintBoardViewWithFrame:self.view.bounds
                                                                       lineWidth:0
                                                                       lineColor:nil
                                                                      boardColor:nil
                                                                     paintResult:^(UIImage * _Nullable image) {
    
            if (image) {
                NSData *data = UIImagePNGRepresentation(image);
                [data writeToFile:@"/Users/JHQ0228/Desktop/Images/pic.png" atomically:YES];
            }
        }];
    
        [self.view addSubview:paintBoard];
    • 效果

      Quartz2D106Quartz2D107

      Quartz2D108Quartz2D109

      Quartz2D110Quartz2D111

目录
相关文章
|
iOS开发
iOS开发-聊天气泡的绘制和聊天消息列表
iOS开发-聊天气泡的绘制和聊天消息列表
242 0
iOS开发-聊天气泡的绘制和聊天消息列表
|
JSON 搜索推荐 Serverless
iOS绘制物理按钮 - 透明圆角渐变边框
iOS绘制物理按钮 - 透明圆角渐变边框
388 0
iOS绘制物理按钮 - 透明圆角渐变边框
|
iOS开发 MacOS
IOS之Quartz
IOS之Quartz
152 0
IOS之Quartz
|
iOS开发
iOS开发UI篇 - Quartz 2D简单使用
iOS开发UI篇 - Quartz 2D简单使用
iOS开发UI篇 - Quartz 2D简单使用
|
缓存 编解码 并行计算
iOS 开发:绘制像素到屏幕
像素是如何绘制到屏幕上面的?把数据输出到屏幕的方法有很多,通过调用很多不同的framework和不同的函数。这里我们讲一下这个过程背后的东西。希望能够帮助大家了解什么时候该使用什么API,特别是当遇到性能问题需要调试的时候。当然,我们这里主要讲iOS,但是事实上,很多东西也是可以应用到OSX上面的。
320 0
iOS 开发:绘制像素到屏幕
|
计算机视觉 iOS开发
|
iOS开发
iOS:quartz2D绘图(给图形绘制阴影)
quartz2D既可以绘制原始图形,也可以给原始图形绘制阴影。 绘制阴影时,需要的一些参数:上下文、阴影偏移量、阴影模糊系数 注意:在drawRect:方法中同时调用绘制同一个图形时,在对绘制的图形做绘制阴影处理前,需要先对上下文进行保存,绘制阴影成功后,还要对上下文进行复位,还原为最原始的上下文。
1175 0