CGContextSaveGState(重點) 與 UIGraphicsPushContext

有一個需求敢艰,每次push一個頁面的時候诬乞,push過去的頁面的背景圖片需要時上一個頁面的樣子。钠导。震嫉。不知道有沒有用這短小精干的語言描述清楚。

<br />

那么這個需求我是這么考慮的牡属,把window轉(zhuǎn)換成image票堵,然后傳入下一個頁面。

<br />

所以接觸了一下Quart2D逮栅。

<br />

今天就來說說CGContextSaveGState(主要)悴势,UIGraphicsPushContext窗宇。

- (void)drawRect:(CGRect)rect{ // do drawing here}

在iOS繪圖的時候大家都會用到這個這個方法。
在調(diào)用這個方法之前瞳浦,繪畫系統(tǒng)創(chuàng)建了一個上下文(CGContext)担映,也可以說是畫布。上下文中包含了很多信息叫潦,比如畫筆顏色蝇完,字體顏色,填充顏色矗蕊,字體短蜕,形狀等等。
由于只有一個CGContext傻咖,也就是說只有一個畫筆朋魔,如果你變化了畫筆的顏色等狀態(tài),就會影響函數(shù)調(diào)用的結(jié)果卿操,那么我們就會用到CGContextSaveGState與CGContextRestoreGState將上下文入棧出棧警检。

通常CGContextSaveGState和CGContextRestoreGState都是成對出現(xiàn)的。

<br />

- (void)drawRect:(CGRect)rect{ 
    //1.獲得當(dāng)前上下文
    CGContextRef context=UIGraphicsGetCurrentContext(); 
    //2.設(shè)置畫筆顏色為紅色害淤,并入棧上下文扇雕,之后把畫筆改為黑色,然后出棧上下文窥摄,你會發(fā)現(xiàn)畫筆又變?yōu)榱俗畛醯募t色镶奉。
    [[UIColor redColor] setStroke];       
    CGContextSaveGState(UIGraphicsGetCurrentContext());   
    [[UIColor blackColor] setStroke]; 
    CGContextRestoreGState(UIGraphicsGetCurrentContext());   
    UIRectFill(CGRectMake(10, 10, 100, 100)); // 紅
}

UIGraphicsPushContext

如果這段代碼中的CGContextSaveGState和CGContextRestoreGState換成UIGraphicsPushContext和UIGraphicsPopContext就不對了。
因為UIGraphicsPushContext并沒有保存該上下文當(dāng)前狀態(tài)的功能崭放,而是完全的切換上下文哨苛。

那么什么時候會用到UIGraphicsPushContext呢?

假設(shè)你正在當(dāng)前視圖上下文中繪制什么東西币砂,這時想要在位圖上下文中繪制完全不同的東西建峭。如果要使用UIKit來進行任意繪圖,你會希望保存當(dāng)前的UIKit上下文决摧,包括所有已經(jīng)繪制的內(nèi)容迹缀,接著切換到一個全新的繪圖上下文中。這就是UIGraphicsPushContext的功能蜜徽。創(chuàng)建完位圖后,再將你的舊上下文出棧票摇。而這就是UIGraphicsPopContext的功能拘鞋。這種情況只會在要使用UIKit在新的位圖上下文中繪圖時才會發(fā)生。只要你使用的是Core Graphics函數(shù)矢门,就不需要去執(zhí)行上下文入棧和出棧盆色,因為Core Graphics函數(shù)將上下文視作參數(shù)灰蛙。(摘錄自http://blog.csdn.net/lihangqw/article/details/9969961

接下來就說說UIImage繪制的一些操作

一般步驟為:
UIGraphicsBeginImageContext(CGSize size)
或者
UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)
準(zhǔn)備繪圖環(huán)境
CGContextRef __nullable UIGraphicsGetCurrentContext(void)
獲取繪圖的CGContextRef
開始繪圖
UIImage* UIGraphicsGetImageFromCurrentImageContext(void);
獲取當(dāng)前繪制的圖形
void UIGraphicsEndImageContext(void);
關(guān)閉繪圖環(huán)境

接下來就從幾個簡單的?? 中體會一下吧~
//圖片按比例壓縮
-(UIImage *)image:(UIImage *)img toScale:(float)scale {
      UIGraphicsBeginImageContext(CGSizeMake(img.size.width, img.size.height)); //準(zhǔn)備繪畫環(huán)境
      [img drawInRect:CGRectMake(0, 0, img.size.width * scale, img.size.height * scale)];//繪畫
      UIImage *endImg = UIGraphicsGetImageFromCurrentImageContext();//獲取當(dāng)前繪制的圖形
      UIGraphicsEndImageContext();//結(jié)束繪畫
      return endImg;
}
//將UIView轉(zhuǎn)為UIImage
- (UIImage *)captureView:(UIView *)theView {
    
    CGRect rect = theView.frame;
    
    UIGraphicsBeginImageContext(rect.size);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextTranslateCTM(context, 0, -70); //截取位置下移70
    
    [theView.layer renderInContext:context];
    
    UIImage *endImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return endImage;
    
}
//截取圖片

- (UIImage *)getImageWithImage:(UIImage *)img {
    
    CGRect myRect = CGRectMake(10, 10,300, 300);
    
    CGImageRef bigRef = img.CGImage;
    
    CGImageRef subImageRef = CGImageCreateWithImageInRect(bigRef, myRect);
    
    CGSize size = CGSizeMake(300, 300);
    
    UIGraphicsBeginImageContext(size);
    
    CGContextDrawImage(UIGraphicsGetCurrentContext(), myRect, subImageRef);
    
    UIImage *smallImage = [UIImage imageWithCGImage:subImageRef];
    
    UIGraphicsEndImageContext();
    
    return smallImage;
    
}
//截取當(dāng)前屏幕
+ (UIImage *)screenshot
{
    CGSize imageSize = [[UIScreen mainScreen] bounds].size;
 
    UIGraphicsBeginImageContext(imageSize);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        if (![window respondsToSelector:@selector(screen)] || [window screen] == [UIScreen mainScreen]) {
            CGContextSaveGState(context);

            CGContextTranslateCTM(context, [window center].x, [window center].y);

            CGContextConcatCTM(context, [window transform]);
            
            CGContextTranslateCTM(context,
                                  -[window bounds].size.width * [[window layer] anchorPoint].x,
                                  -[window bounds].size.height * [[window layer] anchorPoint].y);
            
            [[window layer] renderInContext:context];
            
            CGContextRestoreGState(context);
        }
    }
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return image;
}
//將兩張圖片合成一張

- (UIImage *)addImageWithImage1:(UIImage *)image1 Image2:(UIImage *)image2 {
    
    UIGraphicsBeginImageContext(image1.size);
    
    [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
    
    [image2 drawInRect:CGRectMake(0, 0, image2.size.width-200, image2.size.height-200)];
    
    UIImage *endImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return endImage;
    
}
//截取scrollview

-(UIImage *)captureScrollView:(UIScrollView *)scrollView{

    UIImage* image = nil;

    UIGraphicsBeginImageContext(scrollView.contentSize);

    scrollView.contentOffset = CGPointZero;

    scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);

    [scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];

    image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return image;

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市隔躲,隨后出現(xiàn)的幾起案子摩梧,更是在濱河造成了極大的恐慌,老刑警劉巖宣旱,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仅父,死亡現(xiàn)場離奇詭異,居然都是意外死亡浑吟,警方通過查閱死者的電腦和手機笙纤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來组力,“玉大人省容,你說我怎么就攤上這事×亲郑” “怎么了腥椒?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長候衍。 經(jīng)常有香客問我笼蛛,道長,這世上最難降的妖魔是什么脱柱? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任伐弹,我火速辦了婚禮,結(jié)果婚禮上榨为,老公的妹妹穿的比我還像新娘惨好。我一直安慰自己,他們只是感情好随闺,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布日川。 她就那樣靜靜地躺著,像睡著了一般矩乐。 火紅的嫁衣襯著肌膚如雪龄句。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天散罕,我揣著相機與錄音分歇,去河邊找鬼。 笑死欧漱,一個胖子當(dāng)著我的面吹牛职抡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播误甚,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缚甩,長吁一口氣:“原來是場噩夢啊……” “哼谱净!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起擅威,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤壕探,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后郊丛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體李请,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年宾袜,在試婚紗的時候發(fā)現(xiàn)自己被綠了捻艳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡庆猫,死狀恐怖认轨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情月培,我是刑警寧澤嘁字,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杉畜,受9級特大地震影響纪蜒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜此叠,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一纯续、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧灭袁,春花似錦猬错、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至软瞎,卻和暖如春逢唤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涤浇。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工鳖藕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人只锭。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓吊奢,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子页滚,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

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