图形上下文:
图形上下文表示绘图目的地。它包含绘图参数和绘图系统需要执行任何随后的绘图命令的所有设备特定信息。图形上下文定义基本绘图属性,如绘图时的颜色,剪裁区域,线的宽度和样式信息,字体信息,合成选项,和其他。
你可以通过使用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这个方法来控制是否允许抗锯齿,这种设置不是图形状态的一部分。
锯齿与抗锯齿的比较显而易见。