iOS 繪圖-Quartz2D

Core Graphics Framework是一套基于C的API框架,使用了Quartz作為繪圖引擎舶替。它提供了低級(jí)別、輕量級(jí)顾瞪、高保真度的2D渲染。
Core Graphics API所有的操作都在上下文中進(jìn)行栖茉。所以在繪圖之前需要獲取該上下文并傳入執(zhí)行渲染的函數(shù)內(nèi)孵延。


一、 Quartz2D

Quartz2D的API是純C語(yǔ)言的尘应,它是一個(gè)二維繪圖引擎。在iOS開發(fā)中很重要的一個(gè)價(jià)值是:自定義view(自定義UI控件)苍鲜。

使用Quartz2D自定義View

(1)獲取圖形上下文玷犹。圖形上下文相當(dāng)于畫布,是繪畫的地方,會(huì)保存繪圖信息歹颓、繪圖狀態(tài)。

圖形上下文:
//獲取當(dāng)前圖形上下文
1. CGContextRef ctx = UIGraphicsGetCurrentContext();
//創(chuàng)建一個(gè)圖片類型的上下文
2. UIGraphicsBeginImageContextWithOptions

(2)圖形上下文必須與需要自定義的view相關(guān)聯(lián)领跛,才能將內(nèi)容繪制到view上面撤奸。

自定義view的步驟:
  1. 新建一個(gè)類,繼承自UIView
  2. 實(shí)現(xiàn)- (void)drawRect:(CGRect)rect方法胧瓜,然后在這個(gè)方法中
    a. 取得跟當(dāng)前view相關(guān)聯(lián)的圖形上下文
    b .繪制相應(yīng)的圖形內(nèi)容(內(nèi)容就是路徑path)
    path的表現(xiàn)形式有多種:
    1. CGContextMoveToPoint(需在圖形上下文中操作)
    2. UIBezierPath
    3. CGMutablePathRef
  3. 利用圖形上下文將繪制的所有內(nèi)容渲染顯示到view上面
Quartz2D的管理原則:

(1)使用含有“Create”或“Copy”的函數(shù)創(chuàng)建的對(duì)象(即retain了一個(gè)對(duì)象)贷痪,使用完后必須釋放(release),否則將導(dǎo)致內(nèi)存泄露

(2)使用不含有“Create”或“Copy”的函數(shù)獲取的對(duì)象劫拢,則不需要釋放

核心方法drawRect:
  1. 為什么要實(shí)現(xiàn)drawRect:方法才能繪圖到view上?
    因?yàn)樵赿rawRect:方法中才能取得跟view相關(guān)聯(lián)的圖形上下文
  2. drawRect:方法在什么時(shí)候被調(diào)用妹沙?
    當(dāng)view第一次顯示到屏幕上時(shí)(被加到UIWindow上顯示出來(lái))
    調(diào)用view的setNeedsDisplay或者setNeedsDisplayInRect:時(shí).
  3. 注意4點(diǎn):
    • 手動(dòng)調(diào)用drawRect:方法熟吏,不會(huì)自動(dòng)創(chuàng)建跟View相關(guān)聯(lián)的上下文。應(yīng)該 調(diào)用setNeedsDisplay方法,系統(tǒng)底層會(huì)自動(dòng)調(diào)用drawRect牵寺,告訴系統(tǒng)重新繪制View.這樣,系統(tǒng)底層會(huì)自動(dòng)創(chuàng)建跟View相關(guān)聯(lián)的上下文
  • setNeedsDisplay底層會(huì)調(diào)用drawRect,并不是立馬調(diào)用的.只是設(shè)了一個(gè)調(diào)用的標(biāo)志.調(diào)用時(shí)刻是等下一次屏幕刷新時(shí)才去調(diào)用drawRect趣斤。屏幕每一秒刷新60秒次,所以1秒調(diào)用drawRect方法大概60次,速度非忱栊荩快

  • view內(nèi)部有個(gè)layer(圖層)屬性,drawRect:方法中取得的是一個(gè)Layer Graphics Context势腮,因此,繪制的東西其實(shí)是繪制到- view的layer上去了

  • View之所以能顯示東西泪幌,完全是因?yàn)樗鼉?nèi)部的layer


二署照、 繪畫

Quartz2D重要函數(shù)(C函數(shù))
//起點(diǎn)
CGContextMoveToPoint(CGContextRef c, CGFloat x, CGFloat y)
//添加線段到某個(gè)點(diǎn)
CGContextAddLineToPoint(CGContextRef c, CGFloat x, CGFloat y)
//矩形
CGContextAddRect(CGContextRef c, CGRect rect)
//橢圓
CGContextAddEllipseInRect(CGContextRef context, CGRect rect)
//圓弧 (x,y)圓心  radius:半徑  startAngle:起始角度  endAngle:終止角度 clockwise:時(shí)針方向(順時(shí)針/逆時(shí)針)
CGContextAddArc(CGContextRef c, CGFloat x, CGFloat y,CGFloat radius, CGFloat startAngle, CGFloat endAngle, int clockwise)
//繪制空心路徑
CGContextStrokePath(CGContextRef c)
//繪制實(shí)心路徑
CGContextFillPath(CGContextRef c)
//設(shè)置線段寬度
CGContextSetLineWidth(CGContextRef c, CGFloat width)
//設(shè)置線段頭尾部的樣式
CGContextSetLineCap(CGContextRef c, CGLineCap cap)
//設(shè)置線段轉(zhuǎn)折點(diǎn)的樣式
CGContextSetLineJoin(CGContextRef c, CGLineJoin join)
//設(shè)置顏色
1.不常用
CGContextSetRGBStrokeColor(CGContextRef c, CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
CGContextSetRGBFillColor(CGContextRef c, CGFloat red,CGFloat green, CGFloat blue, CGFloat alpha)
2.常用
[[UIColor brownColor] set]

畫圖

- (void)drawRect:(CGRect)rect {
    
    CGFloat rectW = rect.size.width;
    CGFloat rectH = rect.size.height;
    //取得跟當(dāng)前view相關(guān)聯(lián)的圖形上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    //繪制相應(yīng)的圖形內(nèi)容
    CGContextMoveToPoint(ctx, rectW*.5, 0);
    CGContextAddLineToPoint(ctx, 0, rectH*.5);
    CGContextAddLineToPoint(ctx, rectW*.3, rectH*.5);
    CGContextAddLineToPoint(ctx, rectW*.3, rectH);
    CGContextAddLineToPoint(ctx, rectW*.7, rectH);
    CGContextAddLineToPoint(ctx, rectW*.7, rectH*.5);
    CGContextAddLineToPoint(ctx, rectW, rectH*.5);
    CGContextAddLineToPoint(ctx, rectW*.5, 0);
    CGContextClosePath(ctx);
    
    CGContextSetLineWidth(ctx, 6);
    CGContextSetLineJoin(ctx, kCGLineJoinRound);
    [[UIColor blueColor] set];
  //利用圖形上下文將繪制的所有內(nèi)容渲染顯示到view上面
    CGContextStrokePath(ctx);
}

效果

arrowhead.png

加水印

- (void)addWaterMarkRect:(CGRect)rect {
    
    UIImageView *imageView = [[UIImageView alloc]init];
    imageView.frame = self.bounds;
    [self addSubview:imageView];
    
    //1.加載圖片
    UIImage *image = [UIImage imageNamed:@"rest"];
    //2.創(chuàng)建位圖上下文(size:開啟多大的上下文,就會(huì)生成多大的圖片)
    UIGraphicsBeginImageContext(rect.size);
    //3.把圖片繪制到上下文當(dāng)中(drawAtPoint:可以多次繪制浴滴,不是重置)
    [image drawAtPoint:CGPointZero];
    //4.繪制水印
    NSString *str = @"ONCE";
    NSMutableDictionary *mutableDic = [NSMutableDictionary dictionary];
    mutableDic[NSFontAttributeName] = [UIFont boldSystemFontOfSize:20];
    mutableDic[NSForegroundColorAttributeName] = [UIColor orangeColor];
    NSShadow *shadow = [[NSShadow alloc]init];
    shadow.shadowOffset = CGSizeMake(2, 2);
    shadow.shadowColor = [UIColor orangeColor];
    shadow.shadowBlurRadius = 2;
    mutableDic[NSShadowAttributeName] = shadow;
    [str drawAtPoint:self.bounds.origin withAttributes:mutableDic];
    [str drawAtPoint:CGPointMake(rect.size.width-70, rect.size.height-30) withAttributes:mutableDic];
    //5.從上下文當(dāng)中生成一張圖片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    //6.關(guān)閉位圖上下文
    UIGraphicsEndImageContext();

    imageView.image = newImage;

}

效果

addWaterMark.png

注:在上面的繪制水印部分升略,不一定對(duì)文字操作屡限,也可以直接操作UILabel等視圖來(lái)實(shí)現(xiàn)想要的效果

截屏

- (void)Screenshots
{
    //生成圖片
    //1.開啟一個(gè)位圖上下文
    UIGraphicsBeginImageContext(self.view.bounds.size);
    //2.把View的內(nèi)容繪制到上下文當(dāng)中
    CGContextRef ctx =  UIGraphicsGetCurrentContext();
    //UIView內(nèi)容想要繪制到上下文當(dāng)中, 必須使用渲染的方式
    [self.view.layer renderInContext:ctx];
    //3.從上下文當(dāng)中生成一張圖片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    //4.關(guān)閉上下文
    UIGraphicsEndImageContext();
    //把圖片轉(zhuǎn)成二進(jìn)制流
    //NSData *data = UIImageJPEGRepresentation(newImage, 1);
    NSData *data = UIImagePNGRepresentation(newImage);
    
    [data writeToFile:@"/Users/ONCE/Downloads/ONCE.jpg" atomically:YES];
}

參考資料:
iOS Quartz2D詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钧大,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子啊央,更是在濱河造成了極大的恐慌涨醋,老刑警劉巖逝撬,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異溯警,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)狡相,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喳挑,“玉大人萄金,你說(shuō)我怎么就攤上這事⊙醺遥” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵浙炼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我弯屈,道長(zhǎng)恋拷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任蔬顾,我火速辦了婚禮,結(jié)果婚禮上窄刘,老公的妹妹穿的比我還像新娘。我一直安慰自己娩践,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布材泄。 她就那樣靜靜地躺著,像睡著了一般脸爱。 火紅的嫁衣襯著肌膚如雪遇汞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天络它,我揣著相機(jī)與錄音歪赢,去河邊找鬼。 笑死埋凯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的白对。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蟀瞧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了悦污?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤切端,失蹤者是張志新(化名)和其女友劉穎顷啼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體线梗,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年瘾婿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抢呆。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笛谦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饥脑,到底是詐尸還是另有隱情,我是刑警寧澤灶轰,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站笋颤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏伴澄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一举农、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧并蝗,春花似錦、人聲如沸滚停。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)突雪。三九已至,卻和暖如春咏删,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背督函。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工激挪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留锋叨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓薄湿,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親偷卧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載:http://www.reibang.com/p/32fcadd12108 每個(gè)UIView有一個(gè)伙伴稱為l...
    F麥子閱讀 6,193評(píng)論 0 13
  • --繪圖與濾鏡全面解析 概述 在iOS中可以很容易的開發(fā)出絢麗的界面效果炉奴,一方面得益于成功系統(tǒng)的設(shè)計(jì)蛇更,另一方面得益...
    韓七夏閱讀 2,726評(píng)論 2 10
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果赛糟,實(shí)現(xiàn)這些動(dòng)畫的過(guò)程并不復(fù)雜,今天將帶大家一窺ios動(dòng)畫全貌璧南。在這里你可以看...
    每天刷兩次牙閱讀 8,485評(píng)論 6 30
  • Quartz2D以及drawRect的重繪機(jī)制字?jǐn)?shù)1487 閱讀21 評(píng)論1 喜歡1一、什么是Quartz2D Q...
    PurpleWind閱讀 771評(píng)論 0 3
  • 由于CoreGraphics框架有太多的API豆混,對(duì)于初次接觸或者對(duì)該框架不是十分了解的人动知,在繪圖時(shí),對(duì)API的選擇...
    飛魚灣閱讀 1,031評(píng)論 0 7