CodeV

1.5-在Quartz中构建上下文

Core Graphics使您能够在不使用UIKit入口点的情况下构建位图上下文。此方法使用较旧的API集合,并且在需要逐字节访问绘图数据时非常有用。第3章使用基于Quartz的上下文为其几个图像处理示例提供支持。

清单1-4显示了涉及到的调用。这些突显出了使用Quartz相对于使用UIKit更加地复杂。 这是因为,Quartz使用旧式的Core Foundation系统的对象,以及手动持有和释放模式。

在使用Quartz的代码中,需要总是运行静态分析器(Xcode:Product>Analyze)以检查您的引用是否被正确释放。它提供了一个源代码分析工具,用来发现您的iOS代码中的UIKit方法和Quartz函数的潜在bug。有关LLVM网站上的Clang分析器的更多信息,请访问http://clang-analyzer.llvm.org

在清单1-4中,注意释放模式的迭代性质。如果无法创建上下文,则必须释放颜色空间。在Core Graphics绘图的每个阶段,都会累积一些已分配对象,在从方法或函数返回控制之前(方法或函数结束之前),必须正确地管理这些对象。

最后要注意的是,此示例是如何使用kCGImageAlphaPremultipliedFirst的。 这指定了ARGB字节顺序,使用Quartz友好的alpha预乘法。对于每个像素,alpha值存储在第一个4字节中,蓝色值存储在最后。CGImage.h头文件中的CGImageAlphaInfo定义中记录了这种安排。

清单1-4使用Core Graphics的调用来构建图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Create a color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL){
NSLog(@"Error allocating color space");
return nil;
}

// Create the bitmap context. (Note: in new versions of
// Xcode, you need to cast the alpha setting.)
CGContextRef context = CGBitmapContextCreate(
NULL, width, height,
BITS_PER_COMPONENT, // bits = 8 per component
width * ARGB_COUNT, // 4 bytes for ARGB
colorSpace,
(CGBitmapInfo) kCGImageAlphaPremultipliedFirst);
if (context == NULL){
NSLog(@"Error: Context not created!");
CGColorSpaceRelease(colorSpace );
return nil;
}

// Push the context. // (This is optional. Read on for an explanation of this.)
// UIGraphicsPushContext(context);


// Perform drawing here;

// Balance the context push if used. // UIGraphicsPopContext();

// Convert to image CGImageRef imageRef = CGBitmapContextCreateImage(context);

UIImage *image = [UIImage imageWithCGImage:imageRef];

// Clean up
CGColorSpaceRelease(colorSpace );
CGContextRelease(context);
CFRelease(imageRef);

本文翻译自《iOS Drawing Practical UIKit Solutions》作者:Erica Sadun,翻译:Cheng Dong。如果觉得本书不错请购买支持正版:亚马逊购买传送门,本书所有源代码可在GitHub上下载。译者虽然力求做到信,达,雅,但是由于时间仓促加之译者水平十分有限,文中难免会出现不正确,不准确,词不达意,难于理解的地方,还望各位批评指正,共同进步,谢谢。转载请注明出处。