Quartz 2D图形上下文Graphics Contexts

图形上下文:

        图形上下文表示绘图目的地。它包含绘图参数和绘图系统需要执行任何随后的绘图命令的所有设备特定信息。图形上下文定义基本绘图属性,如绘图时的颜色,剪裁区域,线的宽度和样式信息,字体信息,合成选项,和其他。

        你可以通过使用Quartz上下文创建函数或使用更高级别的功能通过一个Mac OS X的框架或iOS的UIKit框架提供获得一个图形上下文。Quartz提供了各种不同的Quartz图形上下文,包括位图和PDF的功能,您可以使用它来创建自定义内容。

        本章将向您展示如何为各种绘图目的地创建一个图形上下文。图形上下文表示代码中的数据类型CGContextref,这是一个不透明的数据类型。在获得一个图形上下文之后,可以使用Quartz 2D方法来绘制上下文,在上下文中执行操作(如翻译),并改变图形状态参数,如线宽和填充颜色

Drawing to a View Graphics Context in iOS

  在应用程序进行绘制的时候,你需要创建一个UIView对象,然后实现他的drawRect方法。视图的drawRect方法在视图上可见并且内容需要更新的时候调用。在调用自定义的drawRect方法之前,视图对象会自动配置绘图环境是您的代码能立即开始绘制。作为配置的一部分,视图对象为当前的绘图环境创建了一个图形上下文(a CGContextRef opaque type)。你可以drawRect中通过调用UIGraphicsGetCurrentContext方法来获得。需要注意的是UIKit默认的坐标系统是不同于Quartz的坐标系统的。

  Creating a Window Graphics Context in Mac OS X

  打开xcode 新建一个mas os 工程 ,选择cocoa,新建一个NSView的子类:MyQuartzView


context 五个参数。第一个参数表示是否透明,1不透明,0 透明, 最后一参数在不透明时候设置为1,透明的时候可是设置为浮点数。  

可以看到mac运行后坐标系是从左下角开始的,UIKit框架同样。

Creating a PDF Graphics Context 创建PDF上下文

 需要注意的还是PDF的上下文的坐标系统如果绘制在UIview上时,必须转换坐标系统。

创建方式有两种:CGPDFContextCreateWithURL

                            CGPDFContextCreate

  代码片段 官方文档有示例。

Creating a Bitmap Graphics Context  创建位图上下文

一个位图上下文指向了位图的存储空间的存储缓冲区。当你在位图上下文绘制时,缓冲区被更新,在你释放掉上下文后,你将会有你所指定像素格式的全新的位图。

需要注意的是,位图有时被用于离屏绘制,在你决定使用位图进行离屏绘制时,你需要参考 Core Graphics Layer Drawing。CGLayer对象在离屏绘制时做了优化,Quartz对于layer 做了缓存。

iOS注意:iOS应用程序应该使用方法UIGraphicsBeginImageContextWithOptions代替低级的Quartz方法。假如你需要用到位图进行离屏绘制,坐标系统是Quartz 默认的坐标系统。相反的是,当你用UIGraphicsBeginImageContextWithOptions
创建一个image context的时候,坐标系统同样试用,不需要人为调整,尽管那样做没有性能优势。

当你 使用方法CGBitmapContextCreate创建位图上下文的时候,这个方法需要以下几个参数:

          data -----.>数据,提供了一个指针指向你所要渲染的内存。这个内存块的大小最少是 (bytesPerRow*height)字节。

          width -----.>宽度,指定宽度,以像素为单位的位图。

          height -----.>高度,指定高度,以像素为单位的位图。

          bitsPerComponent-----.>指定在内存中的每个像素的每个组件的字节数。例如,为一个32位的像素格式和RGB颜色空间,你可以指定一个8位组件的值。SeeSupported Pixel Formats.

          bytesPerRow------.>指定要使用位图的每行的内存的字节数。

          当你创建一个位图图形上下文,如果你确保数据和bytesperrow 16字节对齐,将获得最佳性能。

          colorspace------.>位图需要的颜色空间。你可以创建一个灰色,RGB,CMYK,或者空的颜色创建位图上下文。更多关于颜色和颜色管理概念详情参考Color Management Overview。更多创建颜色和怎么使用颜色空间参考Color and Color Spaces、。

            bitmapInfo ------.> 位图的布局信息,表示为一个CGBitmapInfo常数,指定位图是否包含透明度的成分和透明度是整数还是浮点数。

  列表2-5显示了如何创建一个位图图形上下文。当您将绘制的位图图形上下文时,Quartz将您的绘制位图记录在指定的内存块中的位图数据中。对每一行代码的详细解释如下所列。

CGContextRef MyCreateBitmapContext (int pixelsWide,

int pixelsHigh)

{

CGContextRef    context = NULL;

CGColorSpaceRef colorSpace;

void *          bitmapData;

int            bitmapByteCount;

int            bitmapBytesPerRow;

bitmapBytesPerRow  = (pixelsWide * 4);// 1 声明了一个变量表示了每行的字节数,这个例子中位图中的一个像素代表是个字节,也就是说red, green, blue, and alpha.各占八位。

bitmapByteCount    = (bitmapBytesPerRow * pixelsHigh);

colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2 创建了一个通用的RGB色彩空间,你还可以创建一个CMYK颜色空间。SeeColor and Color Spaces ,获取更多信息关于通用颜色与设备相关。

bitmapData = calloc( bitmapByteCount );// 3  调用calloc方法来创建一块清晰的内存用来存储位图。

if (bitmapData == NULL)

{

fprintf (stderr, "Memory not allocated!");

return NULL;

}

context = CGBitmapContextCreate (bitmapData,// 4

pixelsWide,

pixelsHigh,

8,      // bits per component

bitmapBytesPerRow,

colorSpace,

kCGImageAlphaPremultipliedLast);    创建一个位图上下文,提供参数比如数据,宽度,高度,每个组件的字节数,每行的字节数,颜色空间,还用一个常数指定透明度存储在每个像素的最后一个字节,颜色已经乘以这个值。SeeThe Alpha Valuefor more information on premultiplied alpha.

if (context== NULL)

{

free (bitmapData);// 5 假如因为某些原因不能创建位图上下文,释放申请内存。

fprintf (stderr, "Context not created!");

return NULL;

}

CGColorSpaceRelease( colorSpace );// 6 释放颜色空间

return context;// 7 

}

接下来就是使用位图创建一个上下文了实现和之前一样的效果

CGRect myBoundingBox;// 1声明一个变量来存储的边界框的起源和尺寸,其中Quartz将绘制从位图上下文创建的图像。

myBoundingBox = CGRectMake (0, 0, myWidth, myHeight);// 2

myBitmapContext = MyCreateBitmapContext (400, 300);// 3 调用上面的函数创建位图上下文。

// ********** Your drawing code here **********// 4

CGContextSetRGBFillColor (myBitmapContext, 1, 0, 0, 1);

CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 200, 100 ));

CGContextSetRGBFillColor (myBitmapContext, 0, 0, 1, .5);

CGContextFillRect (myBitmapContext, CGRectMake (0, 0, 100, 200 ));

myImage = CGBitmapContextCreateImage (myBitmapContext);// 5 根据位图上下文创建一个图形上下文。

CGContextDrawImage(myContext, myBoundingBox, myImage);// 6 绘制图形在指定边框的窗口上下文。边框限定了可以绘制图像的位置和尺寸。

char *bitmapData = CGBitmapContextGetData(myBitmapContext);// 7获取位图上下文的数据。

CGContextRelease (myBitmapContext);// 8释放不再需要时位图图形上下文。

if (bitmapData) free(bitmapData);// 9 释放上下文的内存数据

CGImageRelease(myImage);// 1 释放图形上下文。

效果和上面的截图是一样的。

支持的像素格式

表2-1总结了位图图形上下文支持的像素格式,相关的颜色空间(CS),和在Mac OS X 第一可用的。像素格式指定为位每像素(BPP)和字节/组件(BPC)。该表还包括与该像素格式相关联的位图信息常数。


  Anti-Aliasing  抗锯齿

位图上下文支持抗锯齿。在位图图像中当文本或者图形绘制的时候你经常会看到人工校对的过程中会出现参差不齐的边缘或者其他名字。这些锯齿状会很明显当位图的分辨率低于眼睛的分辨率时。为了使位图中的对象很光滑,Quartz使用不同的像素来包围形状。通过这种混合颜色的方式,形状看起来很平滑。你可以在下图2-4中看到使用了抗锯齿的影响。你也可以关闭反锯齿通过调用CGContextSetShouldAntialias,抗锯齿是graphics state的一部分。你可以通过CGContextSetAllowsAntialiasing这个方法来控制是否允许抗锯齿,这种设置不是图形状态的一部分。

 

         锯齿与抗锯齿的比较显而易见。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,757评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,478评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,540评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,593评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,903评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,329评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,659评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,383评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,055评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,337评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,864评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,227评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,820评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,999评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,750评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,365评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,260评论 2 258

推荐阅读更多精彩内容