- IOS绘图详解
-
Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎。它提供了低级别、轻量级、高保真度的2D渲染。该框架可以用于基于路径的绘图、变换、颜色管理、脱屏渲染,模板、渐变、遮蔽、图像数据管理、图像的创建、遮罩以及PDF文档的创建、显示和分析。为了从感官上对这些概念做一个入门的认识,你可以运行一下官方的example code。 iOS支持两套图形API族:Core Graphics/QuartZ 2D 和OpenGL ES。OpenGL ES是跨平台的图形API,属于OpenGL的一个简化版本。QuartZ 2D是苹果公司开发的一套API,它是Core Graphics Framework的一部分。需要注意的是:OpenGL ES是应用程序 编程接口,该接口描述了方法、结构、函数应具有的行为以及应该如何被使用的语义。也就是说它只定义了一套规范,具体的实现由设备制造商根据规范去做。而往往很多人对接口和实现存在误解。举一个不恰当的比喻:上发条的时钟和装电池的时钟都有相同的可视行为,但两者的内部实现截然不同。因为制造商可以自由的实现Open GL ES,所以不同系统实现的OpenGL ES也存在着巨大的性能差异。 Core Graphics API所有的操作都在一个上下文中进行。所以在绘图之前需要获取该上下文并传入执行渲染的函数中。如果你正在渲染一副在内存中的图片,此时就需要传入图片所属的上下文。获得一个图形上下文是我们完成绘图任务的第一步,你可以将图形上下文理解为一块画布。如果你没有得到这块画布,那么你就无法完成任何绘图操作。当然,有许多方式获得一个图形上下文,这里我介绍两种最为常用的获取方法。 第一种方法就是创建一个图片类型的上下文。调用UIGraphicsBeginImageContextWithOptions函数就可获得用来处理图片的图形上下文。利用该上下文,你就可以在其上进行绘图,并生成图片。调用UIGraphicsGetImageFromCurrentImageContext函数可从当前上下文中获取一个UIImage对象。记住在你所有的绘图操作后别忘了调用UIGraphicsEndImageContext函数关闭图形上下文。 第二种方法是利用cocoa为你生成的图形上下文。当你子类化了一个UIView并实现了自己的drawRect:方法后,一旦drawRect:方法被调用,Cocoa就会为你创建一个图形上下文,此时你对图形上下文的所有绘图操作都会显示在UIView上。 判断一个上下文是否为当前图形上下文需要注意的几点: 1.UIGraphicsBeginImageContextWithOptions函数不仅仅是创建了一个适用于图形操作的上下文,并且该上下文也属于当前上下文。 2.当drawRect方法被调用时,UIView的绘图上下文属于当前图形上下文。 3.回调方法所持有的context:参数并不会让任何上下文成为当前图形上下文。此参数仅仅是对一个图形上下文的引用罢了。 作为初学者,很容易被UIKit和Core Graphics两个支持绘图的框架迷惑。 UIKit 像UIImage、NSString(绘制文本)、UIBezierPath(绘制形状)、UIColor都知道如何绘制自己。这些类提供了功能有限但使用方便的方法来让我们完成绘图任务。一般情况下,UIKit就是我们所需要的。 使用UiKit,你只能在当前上下文中绘图,所以如果你当前处于UIGraphicsBeginImageContextWithOptions函数或drawRect:方法中,你就可以直接使用UIKit提供的方法进行绘图。如果你持有一个context:参数,那么使用UIKit提供的方法之前,必须将该上下文参数转化为当前上下文。幸运的是,调用UIGraphicsPushContext 函数可以方便的将context:参数转化为当前上下文,记住最后别忘了调用UIGraphicsPopContext函数恢复上下文环境。 Core Graphics 这是一个绘图专用的API族,它经常被称为QuartZ或QuartZ 2D。Core Graphics是iOS上所有绘图功能的基石,包括UIKit。 使用Core Graphics之前需要指定一个用于绘图的图形上下文(CGContextRef),这个图形上下文会在每个绘图函数中都会被用到。如果你持有一个图形上下文context:参数,那么你等同于有了一个图形上下文,这个上下文也许就是你需要用来绘图的那个。如果你当前处于UIGraphicsBeginImageContextWithOptions函数或drawRect:方法中,并没有引用一个上下文。为了使用Core Graphics,你可以调用UIGraphicsGetCurrentContext函数获得当前的图形上下文。 至此,我们有了两大绘图框架的支持以及三种获得图形上下文的方法(drawRect:、drawRect: inContext:、UIGraphicsBeginImageContextWithOptions)。那么我们就有6种绘图的形式。如果你有些困惑了,不用怕,我接下来将说明这6种情况。无需担心还没有具体的绘图命令,你只需关注上下文如何被创建以及我们是在使用UIKit还是Core Graphics。 第一种绘图形式:在UIView的子类方法drawRect:中绘制一个蓝色圆,使用UIKit在Cocoa为我们提供的当前上下文中完成绘图任务。1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
) drawRect: (CGRect) rect { </li><li> </li><li
class
=
"alt"
>UIBezierPath* p = [UIBezierPathbezierPathWithOvalInRect:CGRectMake(
0
,
0
,
100
,
100
)]; </li><li> </li><li
class
=
"alt"
>[[UIColor blueColor] setFill]; </li><li> </li><li
class
=
"alt"
>[p fill]; </li><li> </li><li
class
=
"alt"
>} </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
) drawRect: (CGRect) rect { </li><li> </li><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextAddEllipseInRect(con, CGRectMake(
0
,
0
,
100
,
100
)); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor); </li><li> </li><li
class
=
"alt"
>CGContextFillPath(con); </li><li> </li><li
class
=
"alt"
>} </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>
@interface
MyLayerDelegate : NSObject </li><li> </li><li
class
=
"alt"
>
@end
</li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>
@implementation
MyLayerDelegate </li><li> </li><li
class
=
"alt"
>- (
void
)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx { </li><li> </li><li
class
=
"alt"
> UIGraphicsPushContext(ctx); </li><li> </li><li
class
=
"alt"
> UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(
0
,
0
,
100
,
100
)]; </li><li> </li><li
class
=
"alt"
> [[UIColor blueColor] setFill]; </li><li> </li><li
class
=
"alt"
> [p fill]; </li><li> </li><li
class
=
"alt"
> UIGraphicsPopContext(); </li><li> </li><li
class
=
"alt"
>} </li><li> </li><li
class
=
"alt"
>
@end
</li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>
@interface
MyView () { </li><li> </li><li
class
=
"alt"
>MyLayerDelegate* _layerDeleagete; </li><li> </li><li
class
=
"alt"
>} </li><li> </li><li
class
=
"alt"
>
@end
</li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>MyView *myView = [[MyView alloc] initWithFrame: CGRectMake(
0
,
0
,
320
,
480
)]; </li><li> </li><li
class
=
"alt"
>CALayer *myLayer = [CALayer layer]; </li><li> </li><li
class
=
"alt"
>_layerDelegate = [[MyLayerDelegate alloc] init]; </li><li> </li><li
class
=
"alt"
>myLayer.delegate = _layerDelegate; </li><li> </li><li
class
=
"alt"
>[myView.layer addSublayer:myLayer]; </li><li> </li><li
class
=
"alt"
>[myView setNeedsDisplay];
// 调用此方法,drawLayer: inContext:方法才会被调用。 </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
)drawLayer:(CALayer*)lay inContext:(CGContextRef)con { </li><li> </li><li
class
=
"alt"
>CGContextAddEllipseInRect(con, CGRectMake(
0
,
0
,
100
,
100
)); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor); </li><li> </li><li
class
=
"alt"
>CGContextFillPath(con); </li><li> </li><li
class
=
"alt"
>} </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(
100
,
100
), NO,
0
); </li><li> </li><li
class
=
"alt"
>UIBezierPath* p = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(
0
,
0
,
100
,
100
)]; </li><li> </li><li
class
=
"alt"
>[[UIColor blueColor] setFill]; </li><li> </li><li
class
=
"alt"
>[p fill]; </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(
100
,
100
), NO,
0
); </li><li> </li><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextAddEllipseInRect(con, CGRectMake(
0
,
0
,
100
,
100
)); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor); </li><li> </li><li
class
=
"alt"
>CGContextFillPath(con); </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li></ol>
12<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* mars = [UIImage imageNamed:@
"Mars.png"
]; </li><li> </li><li
class
=
"alt"
>CGSize sz = [mars size]; </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*
2
, sz.height), NO,
0
); </li><li> </li><li
class
=
"alt"
>[mars drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>[mars drawAtPoint:CGPointMake(sz.width,
0
)]; </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li><li> </li><li
class
=
"alt"
>UIImageView* iv = [[UIImageView alloc] initWithImage:im]; </li><li> </li><li
class
=
"alt"
>[self.window.rootViewController.view addSubview: iv]; </li><li> </li><li
class
=
"alt"
> iv.center = self.window.center;
</li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* mars = [UIImage imageNamed:@
"Mars.png"
]; </li><li> </li><li
class
=
"alt"
>CGSize sz = [mars size]; </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*
2
, sz.height*
2
), NO,
0
); </li><li> </li><li
class
=
"alt"
>[mars drawInRect:CGRectMake(
0
,
0
,sz.width*
2
,sz.height*
2
)]; </li><li> </li><li
class
=
"alt"
>[mars drawInRect:CGRectMake(sz.width/
2.0
, sz.height/
2.0
, sz.width, sz.height) blendMode:kCGBlendModeMultiply alpha:
1.0
]; </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* mars = [UIImage imageNamed:@
"Mars.png"
]; </li><li> </li><li
class
=
"alt"
>CGSize sz = [mars size]; </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width/
2.0
, sz.height), NO,
0
); </li><li> </li><li
class
=
"alt"
>[mars drawAtPoint:CGPointMake(-sz.width/
2.0
,
0
)]; </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li></ol>
- UIImage* mars = [UIImage imageNamed:@"Mars.png"];
- // 抽取图片的左右半边
- CGSize sz = [mars size];
- CGImageRef marsLeft = CGImageCreateWithImageInRect([mars CGImage],CGRectMake(0,0,sz.width/2.0,sz.height));
- CGImageRef marsRight = CGImageCreateWithImageInRect([mars CGImage],CGRectMake(sz.width/2.0,0,sz.width/2.0,sz.height));
- // 将每一个CGImage绘制到图形上下文中
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*1.5, sz.height), NO, 0);
- CGContextRef con = UIGraphicsGetCurrentContext();
- CGContextDrawImage(con, CGRectMake(0,0,sz.width/2.0,sz.height), marsLeft);
- CGContextDrawImage(con, CGRectMake(sz.width,0,sz.width/2.0,sz.height), marsRight);
- UIImage* im = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- // 记得释放内存,ARC在这里无效
- CGImageRelease(marsLeft);
- CGImageRelease(marsRight); 你也许发现绘出的图是上下颠倒的!图片的颠倒并不是因为被旋转了。当你创建了一个CGImage并使用CGContextDrawImage方法绘图就会引起这种问题。这主要是因为原始的本地坐标系统(坐标原点在左上角)与目标上下文(坐标原点在左下角)不匹配。有很多方法可以修复这个问题,其中一种方法就是使用CGContextDrawImage方法先将CGImage绘制到UIImage上,然后获取UIImage对应的CGImage,此时就得到了一个倒转的CGImage。当再调用CGContextDrawImage方法,我们就将倒转的图片还原回来了。实现代码如下:
1
<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGImageRef flip (CGImageRef im) { </li><li> </li><li
class
=
"alt"
>CGSize sz = CGSizeMake(CGImageGetWidth(im), CGImageGetHeight(im)); </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(sz, NO,
0
); </li><li> </li><li
class
=
"alt"
>CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(
0
,
0
, sz.width, sz.height), im); </li><li> </li><li
class
=
"alt"
>CGImageRef result = [UIGraphicsGetImageFromCurrentImageContext() CGImage]; </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li><li> </li><li
class
=
"alt"
>
return
result; </li><li> </li><li
class
=
"alt"
>} </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextDrawImage(con, CGRectMake(
0
,
0
,sz.width/
2.0
,sz.height), flip(marsLeft)); </li><li> </li><li
class
=
"alt"
>CGContextDrawImage(con, CGRectMake(sz.width,
0
,sz.width/
2.0
,sz.height), flip(marsRight)); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* mars = [UIImage imageNamed:@
"Mars.png"
]; </li><li> </li><li
class
=
"alt"
>CGSize sz = [mars size]; </li><li> </li><li
class
=
"alt"
>
// 转换CGImage并使用对应的CGImage尺寸截取图片的左右部分 </li><li> </li><li class="alt">CGImageRef marsCG = [mars CGImage]; </li><li> </li><li class="alt">CGSize szCG = CGSizeMake(CGImageGetWidth(marsCG), CGImageGetHeight(marsCG)); </li><li> </li><li class="alt">CGImageRef marsLeft = CGImageCreateWithImageInRect(marsCG,CGRectMake(0,0,szCG.width/2.0,szCG.height)); </li><li> </li><li class="alt">CGImageRef marsRight = CGImageCreateWithImageInRect(marsCG, CGRectMake(szCG.width/2.0,0,szCG.width/2.0,szCG.height)); </li><li> </li><li class="alt">UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*1.5, sz.height), NO, 0); </li><li> </li><li class="alt">//剩下的和之前的代码一样,修复倒置问题 </li><li> </li><li class="alt">CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li class="alt">CGContextDrawImage(con, CGRectMake(0,0,sz.width/2.0,sz.height),flip(marsLeft)); </li><li> </li><li class="alt">CGContextDrawImage(con, CGRectMake(sz.width,0,sz.width/2.0,sz.height),flip(marsRight)); </li><li> </li><li class="alt">UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li class="alt">UIGraphicsEndImageContext(); </li><li> </li><li class="alt">CGImageRelease(marsLeft); </li><li> </li><li class="alt">CGImageRelease(marsRight); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* mars = [UIImage imageNamed:@
"Mars.png"
]; </li><li> </li><li
class
=
"alt"
>CGSize sz = [mars size]; </li><li> </li><li
class
=
"alt"
>CGImageRef marsCG = [mars CGImage]; </li><li> </li><li
class
=
"alt"
>CGSize szCG = CGSizeMake(CGImageGetWidth(marsCG), CGImageGetHeight(marsCG)); </li><li> </li><li
class
=
"alt"
>CGImageRef marsLeft = CGImageCreateWithImageInRect(marsCG, CGRectMake(
0
,
0
,szCG.width/
2.0
,szCG.height)); </li><li> </li><li
class
=
"alt"
>CGImageRef marsRight = CGImageCreateWithImageInRect(marsCG, CGRectMake(szCG.width/
2.0
,
0
,szCG.width/
2.0
,szCG.height)); </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(sz.width*
1.5
, sz.height), NO,
0
); </li><li> </li><li
class
=
"alt"
>[[UIImage imageWithCGImage:marsLeft scale:[mars scale] orientation:UIImageOrientationUp] drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>[[UIImage imageWithCGImage:marsRight scale:[mars scale] orientation:UIImageOrientationUp] drawAtPoint:CGPointMake(sz.width,
0
)]; </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li><li> </li><li
class
=
"alt"
>CGImageRelease(marsLeft); CGImageRelease(marsRight); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIImage* moi = [UIImage imageNamed:@
"Mars.jpeg"
]; </li><li> </li><li
class
=
"alt"
>CIImage* moi2 = [[CIImage alloc] initWithCGImage:moi.CGImage]; </li><li> </li><li
class
=
"alt"
>CIFilter* grad = [CIFilter filterWithName:@
"CIRadialGradient"
]; </li><li> </li><li
class
=
"alt"
>CIVector* center = [CIVector vectorWithX:moi.size.width /
2.0
Y:moi.size.height /
2.0
]; </li><li> </li><li
class
=
"alt"
>
// 使用setValue:forKey:方法设置滤镜属性 </li><li> </li><li class="alt">[grad setValue:center forKey:@"inputCenter"]; </li><li> </li><li class="alt">// 在指定滤镜名时提供所有滤镜键值对 </li><li> </li><li class="alt">CIFilter* dark = [CIFilter filterWithName:@"CIDarkenBlendMode" keysAndValues:@"inputImage", grad.outputImage, @"inputBackgroundImage", moi2, nil]; </li><li> </li><li class="alt">CIContext* c = [CIContext contextWithOptions:nil]; </li><li> </li><li class="alt">CGImageRef moi3 = [c createCGImage:dark.outputImage fromRect:moi2.extent]; </li><li> </li><li class="alt">UIImage* moi4 = [UIImage imageWithCGImage:moi3 scale:moi.scale orientation:moi.imageOrientation]; </li><li> </li><li class="alt">CGImageRelease(moi3); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
)drawRect:(CGRect)rect { </li><li> </li><li
class
=
"alt"
>CGContextRef ctx = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSaveGState(ctx); </li><li> </li><li
class
=
"alt"
>{ </li><li> </li><li
class
=
"alt"
>
// 绘图代码 </li><li> </li><li class="alt">} </li><li> </li><li class="alt">CGContextRestoreGState(ctx); </li><li> </li><li class="alt"> } </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorWithColor(con, [UIColor blueColor].CGColor); </li><li> </li><li
class
=
"alt"
>CGContextFillRect(con, rect); </li><li> </li><li
class
=
"alt"
>CGContextClearRect(con, CGRectMake(
0
,
0
,
30
,
30
)); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>
// 绘制一个黑色的垂直黑色线,作为箭头的杆子 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 100, 100); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 19); </li><li> </li><li class="alt">CGContextSetLineWidth(con, 20); </li><li> </li><li class="alt">CGContextStrokePath(con); </li><li> </li><li class="alt">// 绘制一个红色三角形箭头 </li><li> </li><li class="alt">CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); </li><li> </li><li class="alt">CGContextMoveToPoint(con, 80, 25); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 0); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 120, 25); </li><li> </li><li class="alt">CGContextFillPath(con); </li><li> </li><li class="alt">// 从箭头杆子上裁掉一个三角形,使用清除混合模式 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 90, 101); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 90); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 110, 101); </li><li> </li><li class="alt">CGContextSetBlendMode(con, kCGBlendModeClear); </li><li> </li><li class="alt">CGContextFillPath(con); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>UIBezierPath* p = [UIBezierPath bezierPath]; </li><li> </li><li
class
=
"alt"
>[p moveToPoint:CGPointMake(
100
,
100
)]; </li><li> </li><li
class
=
"alt"
>[p addLineToPoint:CGPointMake(
100
,
19
)]; </li><li> </li><li
class
=
"alt"
>[p setLineWidth:
20
]; </li><li> </li><li
class
=
"alt"
>[p stroke]; </li><li> </li><li
class
=
"alt"
>[[UIColor redColor] set]; </li><li> </li><li
class
=
"alt"
>[p removeAllPoints]; </li><li> </li><li
class
=
"alt"
>[p moveToPoint:CGPointMake(
80
,
25
)]; </li><li> </li><li
class
=
"alt"
>[p addLineToPoint:CGPointMake(
100
,
0
)]; </li><li> </li><li
class
=
"alt"
>[p addLineToPoint:CGPointMake(
120
,
25
)]; </li><li> </li><li
class
=
"alt"
>[p fill]; </li><li> </li><li
class
=
"alt"
>[p removeAllPoints]; </li><li> </li><li
class
=
"alt"
>[p moveToPoint:CGPointMake(
90
,
101
)]; </li><li> </li><li
class
=
"alt"
>[p addLineToPoint:CGPointMake(
100
,
90
)]; </li><li> </li><li
class
=
"alt"
>[p addLineToPoint:CGPointMake(
110
,
101
)]; </li><li> </li><li
class
=
"alt"
>[p fillWithBlendMode:kCGBlendModeClear alpha:
1.0
]; </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
)drawRect:(CGRect)rect { </li><li> </li><li
class
=
"alt"
> CGContextRef ctx = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
> CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor); </li><li> </li><li
class
=
"alt"
> CGContextSetLineWidth(ctx,
3
); </li><li> </li><li
class
=
"alt"
> UIBezierPath *path; </li><li> </li><li
class
=
"alt"
> path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(
100
,
100
,
100
,
100
) byRoundingCorners:(UIRectCornerTopLeft |UIRectCornerTopRight) cornerRadii:CGSizeMake(
10
,
10
)]; </li><li> </li><li
class
=
"alt"
> [path stroke]; </li><li> </li><li
class
=
"alt"
>} </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>
// 在上下文裁剪区域中挖一个三角形状的孔 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 90, 100); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 90); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 110, 100); </li><li> </li><li class="alt">CGContextClosePath(con); </li><li> </li><li class="alt">CGContextAddRect(con, CGContextGetClipBoundingBox(con)); </li><li> </li><li class="alt">// 使用奇偶规则,裁剪区域为矩形减去三角形区域 </li><li> </li><li class="alt">CGContextEOClip(con); </li><li> </li><li class="alt">// 绘制垂线 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 100, 100); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 19); </li><li> </li><li class="alt">CGContextSetLineWidth(con, 20); </li><li> </li><li class="alt">CGContextStrokePath(con); </li><li> </li><li class="alt">// 画红色箭头 </li><li> </li><li class="alt">CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); </li><li> </li><li class="alt">CGContextMoveToPoint(con, 80, 25); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 0); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 120, 25); </li><li> </li><li class="alt">CGContextFillPath(con); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSaveGState(con); </li><li> </li><li
class
=
"alt"
>
// 在上下文裁剪区域挖一个三角形孔 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 90, 100); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 90); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 110, 100); </li><li> </li><li class="alt">CGContextClosePath(con); </li><li> </li><li class="alt">CGContextAddRect(con, CGContextGetClipBoundingBox(con)); </li><li> </li><li class="alt">CGContextEOClip(con); </li><li> </li><li class="alt">//绘制一个垂线,让它的轮廓形状成为裁剪区域 </li><li> </li><li class="alt">CGContextMoveToPoint(con, 100, 100); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 19); </li><li> </li><li class="alt">CGContextSetLineWidth(con, 20); </li><li> </li><li class="alt">// 使用路径的描边版本替换图形上下文的路径 </li><li> </li><li class="alt">CGContextReplacePathWithStrokedPath(con); </li><li> </li><li class="alt">// 对路径的描边版本实施裁剪 </li><li> </li><li class="alt">CGContextClip(con); </li><li> </li><li class="alt">// 绘制渐变 </li><li> </li><li class="alt">CGFloat locs[3] = { 0.0, 0.5, 1.0 }; </li><li> </li><li class="alt">CGFloat colors[12] = { </li><li> </li><li class="alt">0.3,0.3,0.3,0.8, // 开始颜色,透明灰 </li><li> </li><li class="alt">0.0,0.0,0.0,1.0, // 中间颜色,黑色 </li><li> </li><li class="alt">0.3,0.3,0.3,0.8 // 末尾颜色,透明灰 </li><li> </li><li class="alt">}; </li><li> </li><li class="alt">CGColorSpaceRef sp = CGColorSpaceCreateDeviceGray(); </li><li> </li><li class="alt">CGGradientRef grad = CGGradientCreateWithColorComponents (sp, colors, locs, 3); </li><li> </li><li class="alt">CGContextDrawLinearGradient(con, grad, CGPointMake(89,0), CGPointMake(111,0), 0); </li><li> </li><li class="alt">CGColorSpaceRelease(sp); </li><li> </li><li class="alt">CGGradientRelease(grad); </li><li> </li><li class="alt">CGContextRestoreGState(con); // 完成裁剪 </li><li> </li><li class="alt">// 绘制红色箭头 </li><li> </li><li class="alt">CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); </li><li> </li><li class="alt">CGContextMoveToPoint(con, 80, 25); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 100, 0); </li><li> </li><li class="alt">CGContextAddLineToPoint(con, 120, 25); </li><li> </li><li class="alt">CGContextFillPath(con); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGColorSpaceRef sp2 = CGColorSpaceCreatePattern(NULL); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorSpace (con, sp2); </li><li> </li><li
class
=
"alt"
>CGColorSpaceRelease (sp2); </li><li> </li><li
class
=
"alt"
>CGPatternCallbacks callback = {
0
, &drawStripes, NULL }; </li><li> </li><li
class
=
"alt"
>CGAffineTransform tr = CGAffineTransformIdentity; </li><li> </li><li
class
=
"alt"
>CGPatternRef patt = CGPatternCreate(NULL,CGRectMake(
0
,
0
,
4
,
4
), tr,
4
,
4
, kCGPatternTilingConstantSpacingMinimalDistortion,
true
, &callback); </li><li> </li><li
class
=
"alt"
>CGFloat alph =
1.0
; </li><li> </li><li
class
=
"alt"
>CGContextSetFillPattern(con, patt, &alph); </li><li> </li><li
class
=
"alt"
>CGPatternRelease(patt); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>
void
drawStripes (
void
*info, CGContextRef con) { </li><li> </li><li
class
=
"alt"
>
// assume 4 x 4 cell </li><li> </li><li class="alt">CGContextSetFillColorWithColor(con, [[UIColor redColor] CGColor]); </li><li> </li><li class="alt">CGContextFillRect(con, CGRectMake(0,0,4,4)); </li><li> </li><li class="alt">CGContextSetFillColorWithColor(con, [[UIColor blueColor] CGColor]); </li><li> </li><li class="alt">CGContextFillRect(con, CGRectMake(0,0,4,2)); </li><li> </li><li class="alt">} </li></ol>
12<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (
void
)drawRect:(CGRect)rect { </li><li> </li><li
class
=
"alt"
>UIGraphicsBeginImageContextWithOptions(CGSizeMake(
40
,
100
), NO,
0.0
); </li><li> </li><li
class
=
"alt"
>CGContextRef con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSaveGState(con); </li><li> </li><li
class
=
"alt"
>CGContextMoveToPoint(con,
90
-
80
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
100
-
80
,
90
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
110
-
80
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextMoveToPoint(con,
110
-
80
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
100
-
80
,
90
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
90
-
80
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextClosePath(con); </li><li> </li><li
class
=
"alt"
>CGContextAddRect(con, CGContextGetClipBoundingBox(con)); </li><li> </li><li
class
=
"alt"
>CGContextEOClip(con); </li><li> </li><li
class
=
"alt"
>CGContextMoveToPoint(con,
100
-
80
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
100
-
80
,
19
); </li><li> </li><li
class
=
"alt"
>CGContextSetLineWidth(con,
20
); </li><li> </li><li
class
=
"alt"
>CGContextReplacePathWithStrokedPath(con); </li><li> </li><li
class
=
"alt"
>CGContextClip(con); </li><li> </li><li
class
=
"alt"
>CGFloat locs[
3
] = {
0.0
,
0.5
,
1.0
}; </li><li> </li><li
class
=
"alt"
>CGFloat colors[
12
] = { </li><li> </li><li
class
=
"alt"
>
0.3
,
0.3
,
0.3
,
0.8
, </li><li> </li><li
class
=
"alt"
>
0.0
,
0.0
,
0.0
,
1.0
, </li><li> </li><li
class
=
"alt"
>
0.3
,
0.3
,
0.3
,
0.8
</li><li> </li><li
class
=
"alt"
>}; </li><li> </li><li
class
=
"alt"
>CGColorSpaceRef sp = CGColorSpaceCreateDeviceGray(); </li><li> </li><li
class
=
"alt"
>CGGradientRef grad = CGGradientCreateWithColorComponents (sp, colors, locs,
3
); </li><li> </li><li
class
=
"alt"
>CGContextDrawLinearGradient (con, grad, CGPointMake(
89
-
80
,
0
), CGPointMake(
111
-
80
,
0
),
0
); </li><li> </li><li
class
=
"alt"
>CGColorSpaceRelease(sp); </li><li> </li><li
class
=
"alt"
>CGGradientRelease(grad); </li><li> </li><li
class
=
"alt"
>CGContextRestoreGState(con); </li><li> </li><li
class
=
"alt"
>CGColorSpaceRef sp2 = CGColorSpaceCreatePattern(NULL); </li><li> </li><li
class
=
"alt"
>CGContextSetFillColorSpace (con, sp2); </li><li> </li><li
class
=
"alt"
>CGColorSpaceRelease (sp2); </li><li> </li><li
class
=
"alt"
>CGPatternCallbacks callback = {
0
, &drawStripes, NULL }; </li><li> </li><li
class
=
"alt"
>CGAffineTransform tr = CGAffineTransformIdentity; </li><li> </li><li
class
=
"alt"
>CGPatternRef patt = CGPatternCreate(NULL,CGRectMake(
0
,
0
,
4
,
4
),tr,
4
,
4
,kCGPatternTilingConstantSpacingMinimalDistortion,
true
, &callback); </li><li> </li><li
class
=
"alt"
>CGFloat alph =
1.0
; </li><li> </li><li
class
=
"alt"
>CGContextSetFillPattern(con, patt, &alph); </li><li> </li><li
class
=
"alt"
>CGPatternRelease(patt); </li><li> </li><li
class
=
"alt"
>CGContextMoveToPoint(con,
80
-
80
,
25
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
100
-
80
,
0
); </li><li> </li><li
class
=
"alt"
>CGContextAddLineToPoint(con,
120
-
80
,
25
); </li><li> </li><li
class
=
"alt"
>CGContextFillPath(con); </li><li> </li><li
class
=
"alt"
>UIImage* im = UIGraphicsGetImageFromCurrentImageContext(); </li><li> </li><li
class
=
"alt"
>UIGraphicsEndImageContext(); </li><li> </li><li
class
=
"alt"
>con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>[im drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>
for
(
int
i=
0
; i<
3
; i++) { </li><li> </li><li
class
=
"alt"
>CGContextTranslateCTM(con,
20
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextRotateCTM(con,
30
* M_PI/
180.0
); </li><li> </li><li
class
=
"alt"
>CGContextTranslateCTM(con, -
20
, -
100
); </li><li> </li><li
class
=
"alt"
>[im drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>} </li><li> </li><li
class
=
"alt"
>}
</li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextTranslateCTM(con,
0
, theHeight); </li><li> </li><li
class
=
"alt"
>CGContextScaleCTM(con,
1.0
, -
1.0
); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextTranslateCTM(con,
0
, sz.height);
// sz为[mars size] </li><li> </li><li class="alt">CGContextScaleCTM(con, 1.0, -1.0); </li><li> </li><li class="alt">CGContextDrawImage(con, CGRectMake(0, 0, sz.width/2.0, sz.height), marsLeft); </li><li> </li><li class="alt">CGContextDrawImage(con, CGRectMake(b.size.width-sz.width/2.0, 0, sz.width/2.0, sz.height),marsRight); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSetShadow(con, CGSizeMake(
7
,
7
),
12
); </li><li> </li><li
class
=
"alt"
>[im drawAtPoint:CGPointMake(
0
,
0
)]; </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>con = UIGraphicsGetCurrentContext(); </li><li> </li><li
class
=
"alt"
>CGContextSetShadow(con, CGSizeMake(
7
,
7
),
12
); </li><li> </li><li
class
=
"alt"
>CGContextBeginTransparencyLayer(con, NULL); </li><li> </li><li
class
=
"alt"
>[im drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>
for
(
int
i=
0
; i<
3
; i++) { </li><li> </li><li
class
=
"alt"
>CGContextTranslateCTM(con,
20
,
100
); </li><li> </li><li
class
=
"alt"
>CGContextRotateCTM(con,
30
* M_PI/
180.0
); </li><li> </li><li
class
=
"alt"
>CGContextTranslateCTM(con, -
20
, -
100
); </li><li> </li><li
class
=
"alt"
>[im drawAtPoint:CGPointMake(
0
,
0
)]; </li><li> </li><li
class
=
"alt"
>} </li><li> </li><li
class
=
"alt"
>
// 在调用了CGContextEndTransparencyLayer函数之后, </li><li> </li><li class="alt">// 图层内容会在应用全局alpha和上下文阴影状态之后被合成到上下文中 </li><li> </li><li class="alt">CGContextEndTransparencyLayer(con); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>CGContextFillRect(con, CGRectMake(
100
,
0
,
1.0
/self.contentScaleFactor,
100
)); </li></ol>
1<ol
class
=
"dp-c"
><li
class
=
"alt"
>- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { </li><li> </li><li
class
=
"alt"
> self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; </li><li> </li><li
class
=
"alt"
> self.window.rootViewController = [UIViewController
new
]; </li><li> </li><li
class
=
"alt"
> MyView* mv =[[MyView alloc] initWithFrame:CGRectMake(
0
,
0
, self.window.bounds.size.width -
50
,
150
)]; </li><li> </li><li
class
=
"alt"
> mv.center = self.window.center; </li><li> </li><li
class
=
"alt"
> [self.window.rootViewController.view addSubview: mv]; </li><li> </li><li
class
=
"alt"
> mv.opaque = NO; </li><li> </li><li
class
=
"alt"
> mv.tag =
111
;
// so I can get a reference to this view later </li><li> </li><li class="alt"> [self performSelector:@selector(resize:) withObject:nil afterDelay:0.1]; </li><li> </li><li class="alt"> self.window.backgroundColor = [UIColor whiteColor]; </li><li> </li><li class="alt"> [self.window makeKeyAndVisible]; </li><li> </li><li class="alt"> return YES; </li><li> </li><li class="alt">} </li></ol>
。