以下几遍关于Quartz 2D博文都是转载自:http://www.cocoachina.com/bbs/u.php?action=topic&uid=38018

iPhone之Quartz 2D系列--图形上下文(2)(Graphics Contexts)

一个Graphics Context表示一个绘制目标。它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息。Graphics Context定义了基本的绘制属性,如颜色、裁减区域、线条宽度和样式信息、字体信息、混合模式等。

我们可以通过几种方式来获取Graphics Context:Quartz提供的创建函数、Mac OS X框架或IOS的UIKit框架提供的函数。Quartz提供了多种Graphics Context的创建函数,包括bitmap和PDF,我们可以使用这些Graphics Context创建自定义的内容。

本章介绍了如何为不同的绘制目标创建Graphics Context。在代码中,我们用CGContextRef来表示一个Graphics Context。当获得一个Graphics Context后,可以使用Quartz 2D函数在上下文(context)中进行绘制、完成操作(如平移)、修改图形状态参数(如线宽和填充颜色)等。

在iOS中的视图Graphics Context进行绘制

在iOS应用程序中,如果要在屏幕上进行绘制,需要创建一个UIView对象,并实现它的drawRect:方法。视图的drawRect:方法在视图显示在屏幕上及它的内容需要更新时被调用。在调用自定义的drawRect:后,视图对象自动配置绘图环境以便代码能立即执行绘图操作。作为配置的一部分,视图对象将为当前的绘图环境创建一个Graphics Context。我们可以通过调用UIGraphicsGetCurrentContext函数来获取这个Graphics Context。

UIKit默认的坐标系统与Quartz不同。在UIKit中,原点位于左上角,y轴正方向为向下。UIView通过将修改Quartz的Graphics Context的CTM[原点平移到左下角,同时将y轴反转(y值乘以-1)]以使其与UIView匹配。

在Mac OS X中创建一个窗口Graphics Context

在Mac OS X中绘制时,我们需要创建一个窗口Graphics Context。Quartz 2D API 没有提供函数来获取窗口Graphics Context。取而代之的是用Cocoa框架来获取一个窗口上下文。

我们可以在Cocoa应用程序的drawRect:中获取一个Quartz Graphics Context,如下代码所示:

复制代码

  1. CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];

currentContext方法在当前线程中返回NSGraphicsContext实例。graphicsPort方法返回一个低级别、平台相关的Graphics Context(Quartz Graphics Context)。

在获取到Graphics Context后,我们可以在Cocoa应用程序中调用任何Quartz 2D的绘制函数。我们同样可以将Quartz 2D与Cocoa绘制操作混合使用。如图2-1是一个在Cocoa视图中用Quartz 2D绘制的实例。绘图由两个长方形组成(一个不透明的红色长方形和半透明的蓝色长方形)。



为了实现图2-1实例,需要先创建一个Cocoa应用程序。在Interface Builder中,拖动一个Custom View到窗口中,并子类化。然后实现子类视图的,如代码清单2-1所示。视图的drawRect:包含了所有的Quartz绘制代码。

引用
注:NSView的drawRect:方法在每次视图需要绘制时自动调用。
复制代码

  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.为视图获取一个Graphics Context


2.插入绘图代码的地方。以下四行是使用Quartz 2D函数的例子


3.设置完全不透明的红色填充色。


4.填充一个长方形,其原点为(0, 0), 大小为(200, 100)


5.设置半透明的蓝色填充色。


6.填充一个长方形,其原点为(0, 0), 大小为(100, 200)

创建一个PDF Graphics Context


当创建一个PDF Graphics Context并绘制时,Quartz将绘制操作记录为一系列的PDF绘制命令并写入文件中。我们需要提供一个PDF输出的位置及一个默认的media box(用于指定页面边界的长方形)。图2-2显示了在PDF Graphics Context中绘制及在preview打开PDF的结果。




Quartz 2D API提供了两个函数来创建PDF Graphics Context:

  • CGPDFContextCreateWithURL:当你需要用Core Foundation URL指定pdf输出的位置时使用该函数。代码清单2-2显示了该函数的使用方法(代码2-2及后面代码的详细解释略):
复制代码

  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:当需要将pdf输出发送给数据用户时使用该方法。代码清单2-3显示了该函数的使用方法:
复制代码

  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显示是如何调用MyPDFContextCreate程序及绘制操作。

复制代码

  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);

我们可以将任何内容(图片,文本,绘制路径)绘制到pdf中,并能添加链接及加密。

创建位图Graphics Context


一个位图Graphics Context接受一个指向内存缓存(包含位图存储空间)的指针,当我们绘制一个位图Graphics Context时,该缓存被更新。在释放Graphics Context后,我们将得到一个我们指定像素格式的全新的位图。

引用
注:位图Graphics Context有时用于后台绘制。CGLayer对象优化了后台绘制,因为Quartz在显卡上缓存了层。
引用
iOS提示:iOS应用程序使用了UIGraphicsBeginImageContextWithOptions取代Quartz低层函数。如果使用Quartz创建一下后台bitmap,bitmap Graphics Context使用的坐标系统是Quartz默认的坐标系统。而使用UIGraphicsBeginImageContextWithOptions创建图形上下文,UIKit将会对坐标系统使用与UIView对象的图形上下文一样的转换。这允许应用程序使用相同的绘制代码而不需要担心坐标系统问题。虽然我们的应用程序可以手动调整CTM达到相同的效果,但这种做没有任何好处。

我们使用CGBitmapContextCreate来创建位图Graphics Context,该函数有如下参数:

  • data:一个指向内存目标的指针,该内存用于存储需要渲染的图形数据。内存块的大小至少需要(bytePerRow * height)字节。
  • width:指定位图的宽度,单位是像素(pixel)。
  • height:指定位图的高度, 单位是像素(pixel)。
  • bitsPerComponent:指定内存中一个像素的每个组件使用的位数。例如,一个32位的像素格式和一个rgb颜色空间,我们可以指定每个组件为8位。
  • bytesPerRow:指定位图每行的字节数。
  • colorspace:颜色空间用于位图上下文。在创建位图Graphics Context时,我们可以使用灰度(gray), RGB, CMYK, NULL颜色空间。
  • bitmapInfo:位图的信息,这些信息用于指定位图是否需要包含alpha组件,像素中alpha组件的相对位置(如果有的话),alpha组件是否是预乘的,及颜色组件是整型值还是浮点值。

代码清单2-5显示了如何创建位图Graphics Context。当向位图Graphics Context绘图时,Quartz将绘图记录到内存中指定的块中。

复制代码

  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显示了调用MyCreateBitmapContext 创建一个位图Graphics Context,使用位图Graphics Context来创建CGImage对象,然后将图片绘制到窗口Graphics Context中。绘制结果如图2-3所示:

复制代码

  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总结了位图Graphics Context支持的像素格式,相关的颜色空间及像素格式支持的Mac OS X最早版本。像素格式用bpp(每像素的位数)和bpc(每个组件的位数)来表示。表格同时也包含与像素格式相关的位图信息常量。

表2-1:位图Graphics Context支持的像素格式

Null 8 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支持反锯齿,这一操作是人为的较正在位图中绘制文本或形状时产生的锯齿边缘。当位图的分辩率明显低于人眼的分辩率时就会产生锯齿。为了使位图中的对象显得平滑,Quartz使用不同的颜色来填充形状周边的像素。通过这种方式来混合颜色,使形状看起来更平滑。如图2-4显示的效果。我们可以通过调用CGContextSetShouldAntialias来关闭位图Graphics Context的反锯齿效果。反锯齿设置是图形状态的一部分。

可以调用函数CGContextSetAllowsAntialiasing来控制一个特定Graphics Context是否支持反锯齿;false表示不支持。该设置不是图形状态的一部分。当上下文及图形状态设置为true时,Quartz执行反锯齿。

获取打印的Graphics Context

Mac OS X中的Cocoa应用程序通过自定义的NSView子类来实现打印。一个视图通过调用print:方法来进行打印。然后视图以打印机为目标创建一个Graphics Context,并调用drawRect:方法。应用程序使用与在屏幕进行绘制相同的绘制代码。我们同样可以自定义drawRect: 方法将图形绘制到打印机。

原帖地址:http://www.cocoachina.com/bbs/read.php?tid=77731&page=2

苹果官网英语介绍:
https://developer.apple.com/library/mac/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_overview/dq_overview.html#//apple_ref/doc/uid/TP30001066-CH202-TPXREF101

iPhone之Quartz 2D系列--图形上下文(2)(Graphics Contexts)的更多相关文章

  1. iPhone之Quartz 2D系列--编程指南(1)概览

    以下几遍关于Quartz 2D博文都是转载自:http://www.cocoachina.com/bbs/u.php?action=topic&uid=38018 iPhone之Quartz ...

  2. Quartz 2D - 图形上下文(Graphics Contexts)

    一个Graphics Context表示一个绘制目标.它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息.Graphics Context定义了基本的绘制属性,如颜色.裁减区域.线条宽度和样式信息 ...

  3. Quartz-2D绘图之图形上下文详解

    上一篇文章大概描述了下Quartz里面大体所包含的东西,但是对具体的细节实现以及如何调用相应API却没有讲.这篇文章就先讲讲图形上下文(Graphics Context)的具体操作. 所谓Graphi ...

  4. Quartz 2D编程指南(2) - 图形上下文

    一个Graphics Context表示一个绘制目标.它包含绘制系统用于完成绘制指令的绘制参数和设备相关信息.Graphics Context定义了基本的绘制属性,如颜色.裁减区域.线条宽度和样式信息 ...

  5. iOS基础 - Quartz 2D绘图

    一.Quartz 2D Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境. Quartz 2D以PDF的规范为基础的图形库,用来绘制二维文字和图形,允许相同的绘图指令在任 ...

  6. Quartz 2D 初步

    转载自:http://www.cofcool.net/development/2015/06/17/ios-study-note-six-Quartz2D/ Quartz 2D是一个二维绘图引擎,同时 ...

  7. 关于Quartz 2D绘图的简单使用

    Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ...

  8. 图形上下文导论(Introduction to SWT Graphics)zz

    图形上下文导论(Introduction to SWT Graphics) 摘要: org.eclipse.swt.graphics包(package),包含了管理图形资源的类.只要实现了org.ec ...

  9. Quartz 2D编程指南(2)图形上下文(Graphics Contexts)

    Graphics Contexts       一个Graphics Context表示一个绘制目标(也能够理解为图形上下文).它包括绘制系统用于完毕绘制指令的绘制參数和设备相关信息.Graphics ...

随机推荐

  1. RedHat7安装Nginx及第三方模块

    编译安装Nginx 先安装编译过程中所需依赖包# yum -y install gcc pcre-devel openssl-devel zlib-devel jemalloc(更好的内存管理)# w ...

  2. Linux netstat命令参数解释

    netstat –ntlp 显示 tcp 的监听端口 netstat –ntlp 显示 tcp udp 的监听端口 netstat –r 显示路由表 netstat –rn 显示路由表不做名称解析(较 ...

  3. virtualbox 安装windows系统的一些问题

    今天总结一下,使用virtualbox安装windows系统的一些问题. 安装的是Ghost的系统,正版系统也可以参考. 首先本人的机器原系统是ubuntu 16.04 LTS x64 1.win7或 ...

  4. JDK自带方法实现RSA非对称加密

    package jdbc.pro.lin; import java.security.InvalidKeyException; import java.security.Key; import jav ...

  5. eAccelerator介绍

    加速器 eAccelerator是一个自由开放源码php加速器,优化和动态内容缓存,提高了php脚本的缓存性能,使得PHP脚本在编译的状态下,对服务器的开销几乎完全消除. 它还有对脚本起优化作用,以加 ...

  6. xml--小结②XML的基本语法

    二.XML的基本语法1.文档声明:作用:用于标识该文档是一个XML文档.注意事项:声明必须出现在文档的第一行(之前连空行都不能有,也不能有任何的注释) 最简单的XML声明:<?xml versi ...

  7. 数据库ACID、隔离级别与MVCC

    首先需要明确事务的概念:一组原子性的SQL查询,如果数据库引擎能够成功的对数据库应用该组查询的全部语句,那么就执行该组语句,否则所有语句都不执行. 事务有ACID四个特性,即: 原子性:一个事务是一个 ...

  8. linux下安装mysql5.6(官方文档)

    Using the MySQL Yum Repository  /  Installing MySQL on Linux Using the MySQL Yum Repository Chapter ...

  9. Sublime Text 3配置LiveReload实现实时刷新

    今天看到一款很强大的插件,LiveReload,实时刷新,也就是说写完html/css/js等不用再到浏览器里按F5啦,在Ctrl+S时浏览器会自动刷新,是不是想想都很爽... Chrome:(据说支 ...

  10. 数据库学习(整理)----6--Oracle如何快速备份和多次备份数表数据

    1.说明:  这里假设一种应用场景! 假设,银行系统中有大量的数据需要及时备份,如何才能快速高效呢! 条件需求: (1).不能设置同步锁(设置的会影响银行正常业务进行!使得银行系统处于维护状态,这是不 ...