首先,我们需要把图片展示在界面上。很简单的操作,唯一需要注意的是由于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);

接下来完成第二个图的效果。第二个图是这样完成的,我们不仅需要加入第一个图绘制的菱形,同时还要把最外层的边框加入到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:

  1. iOS: 使用CGContextRef,CGPath和UIBezierPath来绘画
  2. iOS: 使用CGContextRef中的Transform来辅助作图
  3. iOS: CGPathAddArc和CGPathAddArcToPoint函数
  4. iOS: CGPathRef上绘制渐变颜色
引用链接:
https://www.mgenware.com/blog/?p=478

OS: 剪裁UIImage部分不规则区域的更多相关文章

  1. 截取UIImage指定大小区域

    截取UIImage指定大小区域 最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等.也就是截取UIImage指定大小区域. UIImage扩展 我的解决方案是对UII ...

  2. 【Unity游戏开发】UGUI不规则区域点击的实现

    一.简介 马三从上一家公司离职了,最近一直在出去面试,忙得很,所以这一篇博客拖到现在才写出来.马三在上家公司工作的时候,曾处理了一个UGUI不规则区域点击的问题,制作过程中也有一些收获和需要注意坑,因 ...

  3. C++ 中利用 Opencv 得到不规则的ROI 区域(已知不规则区域)

    因为需要,之前写了一个利用mask 得到不规则ROI 区域的程序. 现在需要修改,发现自己都看不懂是怎么做的了.. 所以把它整理下来. 首先利用 鼠标可以得到 你想要的不规则区域的 顶点信息.具体这里 ...

  4. UGUI实现不规则区域点击响应

    UGUI实现不规则区域点击响应 前言 大家吼啊!最近工作上事情特别多,没怎么打理博客.今天无意打开cnblog才想起该写点东西了.今天给大家讲一个Unity中不规则区域点击响应的实现方法,使用UGUI ...

  5. 【GIS新探索】算法实现在不规则区域内均匀分布点

    1 概要 在不规则区域内均匀分布点,这个需求初看可能不好理解.如果设想一下需求场景就比较简单了. 场景1:在某个地区范围内,例如A市区有100W人口,需要将这100W人口在地图上面相对均匀的标识出来. ...

  6. [OpenGL] 不规则区域的填充算法

    不规则区域的填充算法 一.简单递归 利用Dfs实现简单递归填充. 核心代码: // 简单深度搜索填充 (四连通) void DfsFill(int x, int y) { || y < || x ...

  7. 课题:html5图像羽化(不规则区域羽化,feather,html5羽化)

    下午搜索了一堆相关文章,没有找到符合要求的. 对一张图片应用不规则区域的羽化,该怎么做呢? 首先去查了下 羽化的原理,然而没有什么用, 然后就开始从表现层去研究怎么模拟? idea 1: blur滤镜 ...

  8. OSPF --- 不规则区域实验

    OSPF不规则区域实验: 一.知识点整理: OSPF中路由器的角色(看图): 骨干路由器:路由器所有接口属于area 0  -->R3 非骨干路由器:路由器所有接口属于非area 0  --&g ...

  9. ps如何裁剪掉图片的不规则区域

    按P,鼠标变成钢笔工具,点选住待清除区域,如下: 按ctrl+enter, 将点线变成选中区域: 按delete删除: ctrl+D取消选中区域 完成!

随机推荐

  1. UML: 协作图

    摘自http://www.umlonline.org/school/thread-38-1-1.html UML1.1时,协作图英文名字叫:Collaboration Diagram,UML2.0时, ...

  2. 进击的java - tomcat的安装,配置都正确之后,还是报错

    1.问题 配置Apatch Tomcat过程报错: The CATALINA_HOME environment variable is not defined correctly.This envir ...

  3. WebView自适应屏幕大小

    webView.getSettings().setUseWideViewPort(true); webView.getSettings().setLoadWithOverviewMode(true); ...

  4. paper 59:招聘

     借Valse宝地发条招聘广告:D[腾讯优图]技术大咖招聘 欢迎各位技术大咖尤其应届优秀毕业生投递简历.简历投递:youtu@tencent.com简历投递,邮件标题请按照以下格式:[腾讯_上海_招聘 ...

  5. oracle文件版本

    strings -a  $AU_TOP/forms/US/GLXFCRVL.fmb|grep '$Header' 比如 strings -a /u02/CRP2/apps/apps_st/appl/a ...

  6. RC-50221 问题解决 - netstat 查看端口占用情况

    查看端口占用情况   netstat -an|grep LIST|grep 15     数据库监听占用情况. netstat -an|grep 1521                  1521为 ...

  7. test generation和MBIST

    The problem of test generation Random test generation Deterministic algorithm for test generation fo ...

  8. 运行eclipse提示 The requested resource () is not available.

    不识别web-inf目录,把文件放在Webcontent下就可以运行. 放在其他文件夹里也可以识别.

  9. 将txt文件数据转成bin文件.

    之前用牛逼的绘图以及分析bmp的像素文件的方法, 整理出汉字编码从: 0x4E00到0x9FA5, (维基上说是9FD5, 完了, 回头再更新吧.) https://en.wikipedia.org/ ...

  10. ectouch第四讲 之缓存文件的生成

    当第一次访问\mobile主页的时候,就会生成如下缓存文件:缓存文件存放在\mobile\data\cache\文件夹下 |-mobile |-data |-cache |-compiled [前台编 ...