在畫(huà)布上涂鴉并截取畫(huà)筆軌跡保存到相冊(cè)

有時(shí)候如果想和iPad pro的畫(huà)板一樣涂鴉然后保存后發(fā)給朋友,這時(shí)候在iPhone上怎么實(shí)現(xiàn)呢,下面我就來(lái)一步一步的實(shí)現(xiàn)這個(gè)功能。

按照慣例,先上效果圖:


屏幕快照 2017-09-19 下午2.53.05.png

屏幕快照 2017-09-19 下午2.53.14.png



原理

每當(dāng)畫(huà)筆在畫(huà)布上有所動(dòng)作,都會(huì)將畫(huà)布上新的軌跡保存在一個(gè)全局的可變數(shù)組里,展示的時(shí)候進(jìn)行渲染,如果選擇了撤銷,就清空數(shù)組,重新渲染頁(yè)面。所以不可避免的要用到CGContextRef 上下文來(lái)實(shí)現(xiàn)這一功能。

關(guān)鍵代碼

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //創(chuàng)建筆畫(huà)的數(shù)組
    NSMutableArray *arry=[[NSMutableArray alloc]init];
    //將顏色添加到筆畫(huà)數(shù)組中
    [arry addObject:color];
    [arry addObject:[NSNumber numberWithInt:font]];
    //得到觸摸對(duì)象
    UITouch *touch=[touches anyObject];
    //將觸摸對(duì)象裝化為觸摸點(diǎn)
    CGPoint point=[touch locationInView:self];
    //將point轉(zhuǎn)換為對(duì)象類型
    NSValue *pointValue=[NSValue valueWithCGPoint:point];
    //將得到的起點(diǎn)添加到數(shù)組里面
    [arry addObject:pointValue];
    //將筆畫(huà)數(shù)組放在子數(shù)組里面
    [ziArry addObject:arry];
    
}
- (void)drawRect:(CGRect)rect
{
    //循環(huán)一個(gè)字有多少筆畫(huà)
    for (int i=0; i<[ziArry count]; i++) {
        NSMutableArray *bihua=[ziArry objectAtIndex:i];
        //設(shè)置繪畫(huà)屬性、
        //拿到畫(huà)筆
        contex=UIGraphicsGetCurrentContext();
        //設(shè)置畫(huà)筆的粗細(xì)
        CGContextSetLineWidth(contex, [bihua[1] intValue]);
        //設(shè)置畫(huà)筆的顏色
        CGContextSetStrokeColorWithColor(contex, [bihua[0] CGColor]);
        //內(nèi)層循環(huán)是用來(lái)處理每個(gè)筆畫(huà)有多少個(gè)點(diǎn)
        for (int j=2; j<[bihua count]-2; j++) {
            //將點(diǎn)連成線
            //將對(duì)象類型的點(diǎn)從數(shù)組中取出來(lái)
            NSValue *pointValue=[bihua objectAtIndex:j];
            //將對(duì)象類型轉(zhuǎn)換成point
            CGPoint first=[pointValue CGPointValue];
            //兩點(diǎn)畫(huà)線,取到后面的一個(gè)點(diǎn)
            CGPoint second=[[bihua objectAtIndex:j+1] CGPointValue];
            //設(shè)定線的起點(diǎn)和終點(diǎn)
            CGContextMoveToPoint(contex, first.x, first.y);
            //用點(diǎn)連接成線
            CGContextAddLineToPoint(contex, second.x, second.y);
            //提交畫(huà)筆
            CGContextStrokePath(contex);
            
        }
    }
}

如果想像微信表情一樣發(fā)送的都是有透明度的圖片的話,就必須要使用png格式的圖片了,所以一般的截圖方法就不能用了,因?yàn)槟菢訒?huì)把底部背景也帶上。我們使用另一種辦法UIGraphicsBeginImageContextWithOptions截圖。

//1、獲得圖片的畫(huà)布(上下文)
    //2、畫(huà)布的上下文
    //3、設(shè)置截圖的參數(shù) 截圖
    //4、關(guān)閉圖片的上下文
    //5、保存
    UIGraphicsBeginImageContext(self.frame.size);
    /**
     *  size :圖片尺寸
     * opaque: 是否不透明
     * scale :比例
     */
    UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 1);
    //    [self addRound];
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    [self.layer renderInContext:ctx];
    
    //開(kāi)始截圖
    UIImage *image =   UIGraphicsGetImageFromCurrentImageContext();
    //關(guān)閉截圖上下文
    UIGraphicsEndImageContext();

   //UIImage轉(zhuǎn)換成png
    NSData* imageData =  UIImagePNGRepresentation(image);
    UIImage* pngImage = [UIImage imageWithData:imageData];

github項(xiàng)目地址: https://github.com/hfq-wangqiuyu/PrintView

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,828評(píng)論 25 709
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一種新的協(xié)議。它實(shí)...
    香橙柚子閱讀 24,712評(píng)論 8 183
  • 2017.11.06 星期一 從昨天晚上看到他分享給我的那篇“當(dāng)你丈夫處于爭(zhēng)戰(zhàn)時(shí)”的文章,心里一直非常震撼,波動(dòng)也...
    Ezra的Glory閱讀 183評(píng)論 1 1
  • 文/熊大 2009年,我來(lái)到了魔都。 初到魔都,看到高樓林立,車水馬龍,心里無(wú)比的激動(dòng),并對(duì)未來(lái)充滿了希望。 終于...
    挪威的熊大閱讀 358評(píng)論 0 0
  • 如果說(shuō)女人都是水做的,那么蘭妞、瑩妞、芳妞這三杯水,我會(huì)給她們統(tǒng)統(tǒng)標(biāo)上37度。37度的水溫,無(wú)論是喝下還是用手捧著...
    冰島之鯨閱讀 409評(píng)論 0 3

友情鏈接更多精彩內(nèi)容