首先,我们需要把图片展示在界面上。很简单的操作,唯一需要注意的是由于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. ubuntu安装jdk遇到的问题:cannot execute binary file

    安装完jdk,配置好环境变量出现如下状况: cannot execute binary file 问题原因: jdk的位数与ubuntu的系统位数不一致 jdk 64位 ubuntu 32位 然后通过 ...

  2. java中的Robot

    项目中最近遇到了一个棘手问题,无法用WebDriver去操作win弹出窗口,经过多番查找,发现了Robot这个奇葩东东,Robot可以模拟鼠标和键盘操作, robot可以实现本地系统输入空包括win弹 ...

  3. 使用UIL(Universal-Image-Loader)异步加载图片

    概要: Android-Universal-Image-Loader是一个开源的UI组件程序,该项目的目的是实现可重复使用的异步图像加载.缓存和显示.所以,如果你的程序里需要这个功能的话,使用它,因为 ...

  4. fackbook的Fresco的Image Pipeline以及自身的缓存机制

    fackbook的Fresco的Image Pipeline以及自身的缓存机制 配置之前.首先需要知道两点:一点是Bitmap缓存.一点是如果你仅仅需要一个缓存,那么不调用setSmallImageD ...

  5. 夺命雷公狗ThinkPHP项目之----企业网站24之网站前台获取当前栏目和顶级栏目

    我们现在要实现的是取出网站当前栏目名称和顶级分类名称,如下所示: 列表页的和单页的不能总是写死的吧?? 我能就要想办法去让他变活的才可以解决问题噢,我们已经有了他的cate_id ,然后我们就可以通过 ...

  6. 夺命雷公狗---Thinkphp----15之遍历出来的栏目页的完成

    我们首页的写法和我们的文章页的代码很相似,我们要在点击我们的栏目页的时候遍历出对应的代码: 那么我们就直接来创建一个ListsController.class.php的文件,代码如下所示: 老规矩遍历 ...

  7. 夺命雷公狗---Thinkphp----10之后台登录.注销一条龙

    首先我们还是还是写一个控制器名字叫LoginController.class.php的控制器,首先来写一个code的方法来让验证码先显示出来: public function Code(){ //创建 ...

  8. zw版【转发·台湾nvp系列Delphi例程】HALCON Cast 使用方式

    zw版[转发·台湾nvp系列Delphi例程]HALCON Cast 使用方式 procedure TForm1.Button1Click(Sender: TObject);var img, img1 ...

  9. 【bs4】安装beautifulsoup

    Debian/Ubuntu,install $ apt-get install python-bs4 easy_install/pip $ easy_install beautifulsoup4 $ ...

  10. ApkDec android反编译工具

    转自:http://www.newasp.net/soft/70498.html 下载 ApkDec是一款免费的绿色APK反编译工具 forandroid ,由android开发者社区开发. ApkD ...