效果如下图:
首先,在工程Bundle中加入测试用的图片文件,比如“meteoralp.jpg”。
首先,我们需要把图片展示在界面上。很简单的操作,唯一需要注意的是由于CGContextDrawImage会使用Quartz内以左下角为(0,0)点的坐标系,所以需要使用CGContextTranslateCTM函数和CGContextScaleCTM函数把以左下角为0点的坐标系转化成左上角形式的坐标系。
ViewController中的代码:
//ViewController中的viewDidLoad方法 - (void)viewDidLoad { //从Bundle中读取图片 UIImage *srcImg = [UIImage imageNamed:@"meteoralp.jpg"]; CGFloat width = srcImg.size.width; CGFloat height = srcImg.size.height; //开始绘制图片 UIGraphicsBeginImageContext(srcImg.size); CGContextRef gc = UIGraphicsGetCurrentContext(); //坐标系转换 //因为CGContextDrawImage会使用Quartz内的以左下角为(0,0)的坐标系 CGContextTranslateCTM(gc, 0, height); CGContextScaleCTM(gc, 1, -1); CGContextDrawImage(gc, CGRectMake(0, 0, width, height), [srcImg CGImage]); //结束绘画 UIImage *destImg = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //创建UIImageView并显示在界面上 UIImageView *imgView = [[UIImageView alloc] initWithImage:destImg]; [self.view addSubview:imgView]; }
图片就显示出来了:
接下来绘制Clip区域。使用Quartz中的Path创建操作去绘制一个菱形边框,最后使用CGContextClip函数把当前Path作为Clip区域。
把下面代码插入到上方“开始绘制图片”和“坐标系转化”之间。因为如果在画完图后在设置Clip区域那就没有任何意义了。
//绘制Clip区域 CGContextMoveToPoint(gc, width/2, 0); CGContextAddLineToPoint(gc, width, height/2); CGContextAddLineToPoint(gc, width/2, height); CGContextAddLineToPoint(gc, 0, height/2); CGContextClosePath(gc); CGContextClip(gc);
OK,运行后第一个图的效果就出来了:
接下来完成第二个图的效果。第二个图是这样完成的,我们不仅需要加入第一个图绘制的菱形,同时还要把最外层的边框加入到Path中。后者可以通过CGContextGetClipBoundingBox函数直接得到。
接下来需要讲一下Even-Odd规则,这个规则其实在诸多平台的绘图框架中都有使用,都也是用在填充或者Clip操作中的。
没有在Apple的文档中找到图,倒是在W3C的SVG标准说明中找到一个不错的解释图:
(引用自http://www.w3.org/TR/SVG/painting.html)
可以看到,所谓Even odd规则就是被偶数条线包围的区域会被填充。
所以,有了外面的大边框,被菱形分割的四个小角就是被偶数条线所包围,Clip会生效。注意使用CGContextEOClip函数来做Even odd模式的Clip操作。
修改上面的“绘制Clip区域”代码如下:
//绘制Clip区域 CGContextMoveToPoint(gc, width/2, 0); CGContextAddLineToPoint(gc, width, height/2); CGContextAddLineToPoint(gc, width/2, height); CGContextAddLineToPoint(gc, 0, height/2); CGContextClosePath(gc); //加入矩形边框并调用CGContextEOClip函数 CGContextAddRect(gc, CGContextGetClipBoundingBox(gc)); CGContextEOClip(gc);
运行结果:
如果你只需要从原图片中截图一个矩形区域,那么可以直接用CGImageRef,如下代码:
//原始UIImage UIImage *srcImg = [UIImage imageNamed:@"meteoralp.jpg"]; //创建CGImageRef并从一个矩形中截取源UIImage的一部分 CGImageRef cgimg = CGImageCreateWithImageInRect(srcImg.CGImage, CGRectInset(CGRectMake(0, 0, srcImg.size.width * srcImg.scale, srcImg.size.height * srcImg.scale), 20, 100)); UIImage *destImg = [UIImage imageWithCGImage:cgimg]; //注意释放CGImageRef,因为创建方法包含Create CGImageRelease(cgimg); //创建UIImageView并显示在界面上 UIImageView *imgView = [[UIImageView alloc] initWithImage:destImg]; [self.view addSubview:imgView];
结果:
有任何疑问,可以到Coldfunction来提问.