OS: 剪裁UIImage部分不规则区域
2016-01-29 11:13
323 查看
首先,我们需要把图片展示在界面上。很简单的操作,唯一需要注意的是由于CGContextDrawImage会使用Quartz内以左下角为(0,0)点的坐标系,所以需要使用CGContextTranslateCTM函数和CGContextScaleCTM函数把以左下角为0点的坐标系转化成左上角形式的坐标系。
ViewController中的代码:
接下来绘制Clip区域。使用Quartz中的Path创建操作去绘制一个菱形边框,最后使用CGContextClip函数把当前Path作为Clip区域。
把下面代码插入到上方“开始绘制图片”和“坐标系转化”之间。因为如果在画完图后在设置Clip区域那就没有任何意义了。
接下来完成第二个图的效果。第二个图是这样完成的,我们不仅需要加入第一个图绘制的菱形,同时还要把最外层的边框加入到Path中。后者可以通过CGContextGetClipBoundingBox函数直接得到。
接下来需要讲一下Even-Odd规则,这个规则其实在诸多平台的绘图框架中都有使用,都也是用在填充或者Clip操作中的。
没有在Apple的文档中找到图,倒是在W3C的SVG标准说明中找到一个不错的解释图:
可以看到,所谓Even odd规则就是被偶数条线包围的区域会被填充。
所以,有了外面的大边框,被菱形分割的四个小角就是被偶数条线所包围,Clip会生效。注意使用CGContextEOClip函数来做Even odd模式的Clip操作。
修改上面的“绘制Clip区域”代码如下:
如果你只需要从原图片中截图一个矩形区域,那么可以直接用CGImageRef,如下代码:
iOS: 使用CGContextRef中的Transform来辅助作图
iOS: CGPathAddArc和CGPathAddArcToPoint函数
iOS: CGPathRef上绘制渐变颜色
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);
接下来完成第二个图的效果。第二个图是这样完成的,我们不仅需要加入第一个图绘制的菱形,同时还要把最外层的边框加入到Path中。后者可以通过CGContextGetClipBoundingBox函数直接得到。
接下来需要讲一下Even-Odd规则,这个规则其实在诸多平台的绘图框架中都有使用,都也是用在填充或者Clip操作中的。
没有在Apple的文档中找到图,倒是在W3C的SVG标准说明中找到一个不错的解释图:
可以看到,所谓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];
Related Posts:
iOS: 使用CGContextRef,CGPath和UIBezierPath来绘画iOS: 使用CGContextRef中的Transform来辅助作图
iOS: CGPathAddArc和CGPathAddArcToPoint函数
iOS: CGPathRef上绘制渐变颜色
引用链接: https://www.mgenware.com/blog/?p=478[/code]
相关文章推荐
- iOS学习之UINavigationController详解与使用(一)添加UIBarButtonItem
- POJ1019-Number Sequence-数数。。
- UIViewController 加载方法顺序
- gcd和NSOperationQueue区别
- requirejs data-main加载总是失败的问题
- ACdream 1427 Nice Sequence(线段树)
- 《iOS Human Interface Guidelines》——Routing
- gradle.build里面创建编译时属性值
- List<KeyValuePair<int, DateTime> 用法
- iOS _ UIButton 标题字体大小颜色位置等
- 小新V4000 UEFI装WIN7系统
- Query execution was&nb…
- 使用Anemometer基于pt-query-diges…
- pt-query-digest分析mysql查询日志
- MySQL主从同步报Client reque…
- hdu 3530 Subsequence
- dpdk中uio技术
- 当一个从XIB创建的视图的子控制器在UI上不显示要想到视图控制器的autoresizingMask属性
- Long Value输出方法
- Android开发笔记-使用Handler机制更新UI的三种解决方案