一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Quartz 2D編程指南(2) - 圖形上下文(Graphics Contexts) | iOS開發(fā)討論區(qū)

 wintelsui 2015-02-28

Quartz 2D編程指南(2) - 圖形上下文(Graphics Contexts)   

Quartz 2D編程指南(1) - 概覽
Quartz 2D編程指南(2) - 圖形上下文(Graphics Contexts)

一個(gè)Graphics Context表示一個(gè)繪制目標(biāo)。它包含繪制系統(tǒng)用于完成繪制指令的繪制參數(shù)和設(shè)備相關(guān)信息。Graphics Context定義了基本的繪制屬性,如顏色、裁減區(qū)域、線條寬度和樣式信息、字體信息、混合模式等。

我們可以通過幾種方式來獲取Graphics Context:Quartz提供的創(chuàng)建函數(shù)、Mac OS X框架或IOS的UIKit框架提供的函數(shù)。Quartz提供了多種Graphics Context的創(chuàng)建函數(shù),包括bitmap和PDF,我們可以使用這些Graphics Context創(chuàng)建自定義的內(nèi)容。

本章介紹了如何為不同的繪制目標(biāo)創(chuàng)建Graphics Context。在代碼中,我們用CGContextRef來表示一個(gè)Graphics Context。當(dāng)獲得一個(gè)Graphics Context后,可以使用Quartz 2D函數(shù)在上下文(context)中進(jìn)行繪制、完成操作(如平移)、修改圖形狀態(tài)參數(shù)(如線寬和填充顏色)等。

在iOS中的視圖Graphics Context進(jìn)行繪制
在iOS應(yīng)用程序中,如果要在屏幕上進(jìn)行繪制,需要?jiǎng)?chuàng)建一個(gè)UIView對(duì)象,并實(shí)現(xiàn)它的drawRect:方法。視圖的drawRect:方法在視圖顯示在屏幕上及它的內(nèi)容需要更新時(shí)被調(diào)用。在調(diào)用自定義的drawRect:后,視圖對(duì)象自動(dòng)配置繪圖環(huán)境以便代碼能立即執(zhí)行繪圖操作。作為配置的一部分,視圖對(duì)象將為當(dāng)前的繪圖環(huán)境創(chuàng)建一個(gè)Graphics Context。我們可以通過調(diào)用UIGraphicsGetCurrentContext函數(shù)來獲取這個(gè)Graphics Context。

UIKit默認(rèn)的坐標(biāo)系統(tǒng)與Quartz不同。在UIKit中,原點(diǎn)位于左上角,y軸正方向?yàn)橄蛳?。UIView通過將修改Quartz的Graphics Context的CTM[原點(diǎn)平移到左下角,同時(shí)將y軸反轉(zhuǎn)(y值乘以-1)]以使其與UIView匹配。

在Mac OS X中創(chuàng)建一個(gè)窗口Graphics Context
在Mac OS X中繪制時(shí),我們需要?jiǎng)?chuàng)建一個(gè)窗口Graphics Context。Quartz 2D API 沒有提供函數(shù)來獲取窗口Graphics Context。取而代之的是用Cocoa框架來獲取一個(gè)窗口上下文。

我們可以在Cocoa應(yīng)用程序的drawRect:中獲取一個(gè)Quartz Graphics Context,如下代碼所示:
復(fù)制代碼
  1. CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];

currentContext方法在當(dāng)前線程中返回NSGraphicsContext實(shí)例。graphicsPort方法返回一個(gè)低級(jí)別、平臺(tái)相關(guān)的Graphics Context(Quartz Graphics Context)。

在獲取到Graphics Context后,我們可以在Cocoa應(yīng)用程序中調(diào)用任何Quartz 2D的繪制函數(shù)。我們同樣可以將Quartz 2D與Cocoa繪制操作混合使用。如圖2-1是一個(gè)在Cocoa視圖中用Quartz 2D繪制的實(shí)例。繪圖由兩個(gè)長(zhǎng)方形組成(一個(gè)不透明的紅色長(zhǎng)方形和半透明的藍(lán)色長(zhǎng)方形)。


為了實(shí)現(xiàn)圖2-1實(shí)例,需要先創(chuàng)建一個(gè)Cocoa應(yīng)用程序。在Interface Builder中,拖動(dòng)一個(gè)Custom View到窗口中,并子類化。然后實(shí)現(xiàn)子類視圖的,如代碼清單2-1所示。視圖的drawRect:包含了所有的Quartz繪制代碼。
引用
注:NSView的drawRect:方法在每次視圖需要繪制時(shí)自動(dòng)調(diào)用。

復(fù)制代碼
  1. Listing 2-1  Drawing to a window graphics context
  2. @implementation MyQuartzView
  3. - (id)initWithFrame:(NSRect)frameRect
  4. {
  5.     self = [super initWithFrame:frameRect];
  6.     return self;
  7. }
  8. - (void)drawRect:(NSRect)rec
  9. {
  10.     CGContextRef myContext = [[NSGraphicsContext  currentContext] graphicsPort]; //1
  11.    // ********** Your drawing code here **********       //2
  12.     CGContextSetRGBFillColor (myContext, 1, 0, 0, 1);     //3
  13.     CGContextFillRect (myContext, CGRectMake (0, 0, 200, 100 ));   //4
  14.     CGContextSetRGBFillColor (myContext, 0, 0, 1, .5);     //5
  15.     CGContextFillRect (myContext, CGRectMake (0, 0, 100, 200));   //6
  16. }
  17. @end

代碼說明:
1.為視圖獲取一個(gè)Graphics Context
2.插入繪圖代碼的地方。以下四行是使用Quartz 2D函數(shù)的例子
3.設(shè)置完全不透明的紅色填充色。
4.填充一個(gè)長(zhǎng)方形,其原點(diǎn)為(0, 0), 大小為(200, 100)
5.設(shè)置半透明的藍(lán)色填充色。
6.填充一個(gè)長(zhǎng)方形,其原點(diǎn)為(0, 0), 大小為(100, 200)

創(chuàng)建一個(gè)PDF Graphics Context
當(dāng)創(chuàng)建一個(gè)PDF Graphics Context并繪制時(shí),Quartz將繪制操作記錄為一系列的PDF繪制命令并寫入文件中。我們需要提供一個(gè)PDF輸出的位置及一個(gè)默認(rèn)的media box(用于指定頁(yè)面邊界的長(zhǎng)方形)。圖2-2顯示了在PDF Graphics Context中繪制及在preview打開PDF的結(jié)果。


Quartz 2D API提供了兩個(gè)函數(shù)來創(chuàng)建PDF Graphics Context:
  • CGPDFContextCreateWithURL:當(dāng)你需要用Core Foundation URL指定pdf輸出的位置時(shí)使用該函數(shù)。代碼清單2-2顯示了該函數(shù)的使用方法(代碼2-2及后面代碼的詳細(xì)解釋略):
復(fù)制代碼
  1. Listing 2-2  Calling CGPDFContextCreateWithURL to create a PDF graphics context
  2. CGContextRef MyPDFContextCreate (const CGRect *inMediaBox, CFStringRef path)
  3. {
  4.     CGContextRef myOutContext = NULL;
  5.     CFURLRef url;
  6.     url = CFURLCreateWithFileSystemPath (NULL, path, kCFURLPOSIXPathStyle, false);
  7.     if (url != NULL) {
  8.         myOutContext = CGPDFContextCreateWithURL (url,  inMediaBox,  NULL);
  9.         CFRelease(url);
  10.     }
  11.     return myOutContext;
  12. }

  • CGPDFContextCreate:當(dāng)需要將pdf輸出發(fā)送給數(shù)據(jù)用戶時(shí)使用該方法。代碼清單2-3顯示了該函數(shù)的使用方法:
復(fù)制代碼
  1. Listing 2-3  Calling CGPDFContextCreate to create a PDF graphics context
  2. CGContextRef MyPDFContextCreate (const CGRect *inMediaBox, CFStringRef path)
  3. {
  4.     CGContextRef        myOutContext = NULL;
  5.     CFURLRef            url;
  6.     CGDataConsumerRef   dataConsumer;
  7.     url = CFURLCreateWithFileSystemPath (NULL,  path, kCFURLPOSIXPathStyle, false);
  8.     if (url != NULL)
  9.     {
  10.         dataConsumer = CGDataConsumerCreateWithURL (url);
  11.         if (dataConsumer != NULL)
  12.         {
  13.             myOutContext = CGPDFContextCreate (dataConsumer, inMediaBox, NULL);
  14.             CGDataConsumerRelease (dataConsumer);
  15.         }
  16.         CFRelease(url);
  17.     }
  18.     return myOutContext;
  19. }

代碼清單2-4顯示是如何調(diào)用MyPDFContextCreate程序及繪制操作。
復(fù)制代碼
  1. Listing 2-4  Drawing to a PDF graphics context
  2.     CGRect mediaBox;
  3.     mediaBox = CGRectMake (0, 0, myPageWidth, myPageHeight);
  4.     myPDFContext = MyPDFContextCreate (&mediaBox, CFSTR("test.pdf"));
  5.     CFStringRef myKeys[1];
  6.     CFTypeRef myValues[1];
  7.     myKeys[0] = kCGPDFContextMediaBox;
  8.     myValues[0] = (CFTypeRef) CFDataCreate(NULL,(const UInt8 *)&mediaBox, sizeof (CGRect));
  9.     CFDictionaryRef pageDictionary = CFDictionaryCreate(NULL, (const void **) myKeys,
  10.                                                         (const void **) myValues, 1,
  11.                                                         &kCFTypeDictionaryKeyCallBacks,
  12.                                                         & kCFTypeDictionaryValueCallBacks);
  13.     CGPDFContextBeginPage(myPDFContext, &pageDictionary);
  14.         // ********** Your drawing code here **********
  15.         CGContextSetRGBFillColor (myPDFContext, 1, 0, 0, 1);
  16.         CGContextFillRect (myPDFContext, CGRectMake (0, 0, 200, 100 ));
  17.         CGContextSetRGBFillColor (myPDFContext, 0, 0, 1, .5);
  18.         CGContextFillRect (myPDFContext, CGRectMake (0, 0, 100, 200 ));
  19.     CGPDFContextEndPage(myPDFContext);
  20.     CFRelease(pageDictionary);
  21.     CFRelease(myValues[0]);
  22.     CGContextRelease(myPDFContext);

我們可以將任何內(nèi)容(圖片,文本,繪制路徑)繪制到pdf中,并能添加鏈接及加密。

創(chuàng)建位圖Graphics Context
一個(gè)位圖Graphics Context接受一個(gè)指向內(nèi)存緩存(包含位圖存儲(chǔ)空間)的指針,當(dāng)我們繪制一個(gè)位圖Graphics Context時(shí),該緩存被更新。在釋放Graphics Context后,我們將得到一個(gè)我們指定像素格式的全新的位圖。
引用
注:位圖Graphics Context有時(shí)用于后臺(tái)繪制。CGLayer對(duì)象優(yōu)化了后臺(tái)繪制,因?yàn)镼uartz在顯卡上緩存了層。

引用
iOS提示:iOS應(yīng)用程序使用了UIGraphicsBeginImageContextWithOptions取代Quartz低層函數(shù)。如果使用Quartz創(chuàng)建一下后臺(tái)bitmap,bitmap Graphics Context使用的坐標(biāo)系統(tǒng)是Quartz默認(rèn)的坐標(biāo)系統(tǒng)。而使用UIGraphicsBeginImageContextWithOptions創(chuàng)建圖形上下文,UIKit將會(huì)對(duì)坐標(biāo)系統(tǒng)使用與UIView對(duì)象的圖形上下文一樣的轉(zhuǎn)換。這允許應(yīng)用程序使用相同的繪制代碼而不需要擔(dān)心坐標(biāo)系統(tǒng)問題。雖然我們的應(yīng)用程序可以手動(dòng)調(diào)整CTM達(dá)到相同的效果,但這種做沒有任何好處。

我們使用CGBitmapContextCreate來創(chuàng)建位圖Graphics Context,該函數(shù)有如下參數(shù):
  • data:一個(gè)指向內(nèi)存目標(biāo)的指針,該內(nèi)存用于存儲(chǔ)需要渲染的圖形數(shù)據(jù)。內(nèi)存塊的大小至少需要(bytePerRow * height)字節(jié)。
  • width:指定位圖的寬度,單位是像素(pixel)。
  • height:指定位圖的高度, 單位是像素(pixel)。
  • bitsPerComponent:指定內(nèi)存中一個(gè)像素的每個(gè)組件使用的位數(shù)。例如,一個(gè)32位的像素格式和一個(gè)rgb顏色空間,我們可以指定每個(gè)組件為8位。
  • bytesPerRow:指定位圖每行的字節(jié)數(shù)。
  • colorspace:顏色空間用于位圖上下文。在創(chuàng)建位圖Graphics Context時(shí),我們可以使用灰度(gray), RGB, CMYK, NULL顏色空間。
  • bitmapInfo:位圖的信息,這些信息用于指定位圖是否需要包含alpha組件,像素中alpha組件的相對(duì)位置(如果有的話),alpha組件是否是預(yù)乘的,及顏色組件是整型值還是浮點(diǎn)值。
代碼清單2-5顯示了如何創(chuàng)建位圖Graphics Context。當(dāng)向位圖Graphics Context繪圖時(shí),Quartz將繪圖記錄到內(nèi)存中指定的塊中。
復(fù)制代碼
  1. Listing 2-5  Creating a bitmap graphics context
  2. CGContextRef MyCreateBitmapContext (int pixelsWide, int pixelsHigh)
  3. {
  4.     CGContextRef    context = NULL;
  5.     CGColorSpaceRef colorSpace;
  6.     void *          bitmapData;
  7.     int             bitmapByteCount;
  8.     int             bitmapBytesPerRow;
  9.     bitmapBytesPerRow   = (pixelsWide * 4);
  10.     bitmapByteCount     = (bitmapBytesPerRow * pixelsHigh);
  11.     colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
  12.     bitmapData = calloc( bitmapByteCount );
  13.     if (bitmapData == NULL)
  14.     {
  15.         fprintf (stderr, "Memory not allocated!");
  16.         return NULL;
  17.     }
  18.     context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
  19.     if (context== NULL)
  20.     {
  21.         free (bitmapData);
  22.         fprintf (stderr, "Context not created!");
  23.         return NULL;
  24.     }
  25.     CGColorSpaceRelease( colorSpace );
  26.     return context;
  27. }

代碼清單2-6顯示了調(diào)用MyCreateBitmapContext 創(chuàng)建一個(gè)位圖Graphics Context,使用位圖Graphics Context來創(chuàng)建CGImage對(duì)象,然后將圖片繪制到窗口Graphics Context中。繪制結(jié)果如圖2-3所示:
復(fù)制代碼
  1. Listing 2-6  Drawing to a bitmap graphics context
  2.     CGRect myBoundingBox;
  3.     myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);
  4.     myBitmapContext = MyCreateBitmapContext (400, 300);
  5.     // ********** Your drawing code here ********** 
  6.     CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1);
  7.     CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 ));
  8.     CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5);
  9.     CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 ));
  10.     myImage = CGBitmapContextCreateImage (myBitmapContext);
  11.     CGContextDrawImage(myContext, myBoundingBox, myImage);
  12.     char *bitmapData = CGBitmapContextGetData(myBitmapContext); 
  13.     CGContextRelease (myBitmapContext);
  14.     if (bitmapData) free(bitmapData); 
  15.     CGImageRelease(myImage);





支持的像素格式
表2-1總結(jié)了位圖Graphics Context支持的像素格式,相關(guān)的顏色空間及像素格式支持的Mac OS X最早版本。像素格式用bpp(每像素的位數(shù))和bpc(每個(gè)組件的位數(shù))來表示。表格同時(shí)也包含與像素格式相關(guān)的位圖信息常量。

表2-1:位圖Graphics Context支持的像素格式
Null8 bpp, 8 bpc, kCGImageAlphaOnly
Mac OS X, iOS
Gray
8 bpp, 8 bpc,kCGImageAlphaNone
Mac OS X, iOS
Gray
8 bpp, 8 bpc,kCGImageAlphaOnly
Mac OS X, iOS
Gray
16 bpp, 16 bpc, kCGImageAlphaNone
Mac OS X
Gray
32 bpp, 32 bpc, kCGImageAlphaNone|kCGBitmapFloatComponents
Mac OS X
RGB
16 bpp, 5 bpc, kCGImageAlphaNoneSkipFirst
Mac OS X, iOS
RGB
32 bpp, 8 bpc, kCGImageAlphaNoneSkipFirst
Mac OS X, iOS
RGB
32 bpp, 8 bpc, kCGImageAlphaNoneSkipLast
Mac OS X, iOS
RGB
32 bpp, 8 bpc, kCGImageAlphaPremultipliedFirst
Mac OS X, iOS
RGB
32 bpp, 8 bpc, kCGImageAlphaPremultipliedLast
Mac OS X, iOS
RGB
64 bpp, 16 bpc, kCGImageAlphaPremultipliedLast
Mac OS X
RGB
64 bpp, 16 bpc, kCGImageAlphaNoneSkipLast
Mac OS X
RGB
128 bpp, 32 bpc, kCGImageAlphaNoneSkipLast |kCGBitmapFloatComponents
Mac OS X
RGB
128 bpp, 32 bpc, kCGImageAlphaPremultipliedLast |kCGBitmapFloatComponents
Mac OS X
CMYK
32 bpp, 8 bpc, kCGImageAlphaNone
Mac OS X
CMYK
64 bpp, 16 bpc, kCGImageAlphaNone
Mac OS X
CMYK
128 bpp, 32 bpc, kCGImageAlphaNone |kCGBitmapFloatComponents
Mac OS X

反鋸齒
位圖Graphics Context支持反鋸齒,這一操作是人為的較正在位圖中繪制文本或形狀時(shí)產(chǎn)生的鋸齒邊緣。當(dāng)位圖的分辯率明顯低于人眼的分辯率時(shí)就會(huì)產(chǎn)生鋸齒。為了使位圖中的對(duì)象顯得平滑,Quartz使用不同的顏色來填充形狀周邊的像素。通過這種方式來混合顏色,使形狀看起來更平滑。如圖2-4顯示的效果。我們可以通過調(diào)用CGContextSetShouldAntialias來關(guān)閉位圖Graphics Context的反鋸齒效果。反鋸齒設(shè)置是圖形狀態(tài)的一部分。
可以調(diào)用函數(shù)CGContextSetAllowsAntialiasing來控制一個(gè)特定Graphics Context是否支持反鋸齒;false表示不支持。該設(shè)置不是圖形狀態(tài)的一部分。當(dāng)上下文及圖形狀態(tài)設(shè)置為true時(shí),Quartz執(zhí)行反鋸齒。




獲取打印的Graphics Context
Mac OS X中的Cocoa應(yīng)用程序通過自定義的NSView子類來實(shí)現(xiàn)打印。一個(gè)視圖通過調(diào)用print:方法來進(jìn)行打印。然后視圖以打印機(jī)為目標(biāo)創(chuàng)建一個(gè)Graphics Context,并調(diào)用drawRect:方法。應(yīng)用程序使用與在屏幕進(jìn)行繪制相同的繪制代碼。我們同樣可以自定義drawRect: 方法將圖形繪制到打印機(jī)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产不卡的视频在线观看| 欧美日韩精品视频在线| 国产在线成人免费高清观看av| 日韩一区二区三区嘿嘿| 亚洲欧美日本国产不卡| 老司机亚洲精品一区二区| 亚洲国产丝袜一区二区三区四| av在线免费观看一区二区三区| 富婆又大又白又丰满又紧又硬 | 欧美日韩一区二区三区色拉拉| 欧美韩日在线观看一区| 黄色日韩欧美在线观看| 国产成人午夜av一区二区| 国产精品午夜一区二区三区| 在线观看免费午夜福利| 国产日韩欧美综合视频| 国产欧美日韩视频91| 久热久热精品视频在线观看| 国产精品推荐在线一区| 亚洲日本加勒比在线播放| 中文字幕人妻av不卡| 国产av乱了乱了一区二区三区| 日韩欧美三级视频在线| 久久精品亚洲欧美日韩| 亚洲综合伊人五月天中文| 亚洲天堂精品在线视频| 五月天丁香亚洲综合网| 亚洲男人天堂成人在线视频| 国产成人av在线免播放观看av| 亚洲欧美黑人一区二区| 亚洲综合色婷婷七月丁香| 色鬼综合久久鬼色88| 91免费一区二区三区| 国产又粗又猛又长又黄视频| 麻豆精品在线一区二区三区| 国产欧美日韩在线一区二区| 日韩欧美第一页在线观看 | 殴美女美女大码性淫生活在线播放| 色婷婷激情五月天丁香| 国产精品一区二区高潮| 日韩成人高清免费在线|