OS: 剪裁UIImage部分不规则区域
首先,我们需要把图片展示在界面上。很简单的操作,唯一需要注意的是由于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:
引用链接:
https://www.mgenware.com/blog/?p=478
OS: 剪裁UIImage部分不规则区域的更多相关文章
- 截取UIImage指定大小区域
截取UIImage指定大小区域 最近遇到这样的需求:从服务器获取到一张照片,只需要显示他的左半部分,或者中间部分等等.也就是截取UIImage指定大小区域. UIImage扩展 我的解决方案是对UII ...
- 【Unity游戏开发】UGUI不规则区域点击的实现
一.简介 马三从上一家公司离职了,最近一直在出去面试,忙得很,所以这一篇博客拖到现在才写出来.马三在上家公司工作的时候,曾处理了一个UGUI不规则区域点击的问题,制作过程中也有一些收获和需要注意坑,因 ...
- C++ 中利用 Opencv 得到不规则的ROI 区域(已知不规则区域)
因为需要,之前写了一个利用mask 得到不规则ROI 区域的程序. 现在需要修改,发现自己都看不懂是怎么做的了.. 所以把它整理下来. 首先利用 鼠标可以得到 你想要的不规则区域的 顶点信息.具体这里 ...
- UGUI实现不规则区域点击响应
UGUI实现不规则区域点击响应 前言 大家吼啊!最近工作上事情特别多,没怎么打理博客.今天无意打开cnblog才想起该写点东西了.今天给大家讲一个Unity中不规则区域点击响应的实现方法,使用UGUI ...
- 【GIS新探索】算法实现在不规则区域内均匀分布点
1 概要 在不规则区域内均匀分布点,这个需求初看可能不好理解.如果设想一下需求场景就比较简单了. 场景1:在某个地区范围内,例如A市区有100W人口,需要将这100W人口在地图上面相对均匀的标识出来. ...
- [OpenGL] 不规则区域的填充算法
不规则区域的填充算法 一.简单递归 利用Dfs实现简单递归填充. 核心代码: // 简单深度搜索填充 (四连通) void DfsFill(int x, int y) { || y < || x ...
- 课题:html5图像羽化(不规则区域羽化,feather,html5羽化)
下午搜索了一堆相关文章,没有找到符合要求的. 对一张图片应用不规则区域的羽化,该怎么做呢? 首先去查了下 羽化的原理,然而没有什么用, 然后就开始从表现层去研究怎么模拟? idea 1: blur滤镜 ...
- OSPF --- 不规则区域实验
OSPF不规则区域实验: 一.知识点整理: OSPF中路由器的角色(看图): 骨干路由器:路由器所有接口属于area 0 -->R3 非骨干路由器:路由器所有接口属于非area 0 --&g ...
- ps如何裁剪掉图片的不规则区域
按P,鼠标变成钢笔工具,点选住待清除区域,如下: 按ctrl+enter, 将点线变成选中区域: 按delete删除: ctrl+D取消选中区域 完成!
随机推荐
- 接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)?
接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)? 1. 接口可以继承接口. 2. 抽像类可以实现(implements)接 ...
- 1021: A除以B
1021: A除以B 时间限制: 1 Sec 内存限制: 128 MB提交: 263 解决: 189[提交][状态][讨论版] 题目描述 本题要求计算A/B,其中A是不超过1000位的正整数,B是 ...
- fackbook的Fresco的Image Pipeline以及自身的缓存机制
fackbook的Fresco的Image Pipeline以及自身的缓存机制 配置之前.首先需要知道两点:一点是Bitmap缓存.一点是如果你仅仅需要一个缓存,那么不调用setSmallImageD ...
- [转]]将 ASP.NET MVC3 Razor 项目部署到虚拟主机中
原链接:http://www.cnblogs.com/taven/archive/2011/08/14/2138077.html 国内很多网站空间都只支持.NET 2.0 和 .NET 3.0 3.5 ...
- c#如实现将一个数字转化为其他进制字符串输出
之前在 os 上看到有人说过 一直想整理 但是一直没时间 后来 从csdn 上 知道了一份 下面内容 来自 (1)http://bbs.csdn.net/topics/60512816 tost ...
- 安装 Apache 出现 <OS 10013> 以一种访问权限不允许的方式做了一个访问套接字的尝试
在安装Apache的过程中出现: 仔细查看提示: make_sock: could not bind to address 0.0.0.0:80 恍然大悟,计算机上安装了IIS7,80端口已占用. 打 ...
- 记centos7中的network.service启动失败
查看启动失败的服务: systemctl --failed 然后就发现了一个叫network.service 的服务启动失败了. 后来找到了原因, 是因为配置文件中没有写上网卡的硬件地址 配置文件所在 ...
- Swift 注释
注释就是对代码的解释和说明.目的是为了让别人和自己很容易看懂.为了让别人一看就知道这段代码是做什么用的. 正确的程序注释一般包括序言性注释和功能性注释.序言性注释的主要内容包括模块的接口.数据的描述和 ...
- ORA-000845 与 /dev/shm(tempfs)
MEMORY_TARGET参数在Oracle 11g被引进,主要是用于控制Oracle对于系统内存的使用,首次将SGA与PGA整合到一起实现自动管理.一旦设置了MEMORY_TARGET参数值,Ora ...
- Java中的线程同步机制
一.首先为什么线程需要同步? 1.多线程安全问题的原因 A:有多线程环境 B:有共享数据 C:有多条语句操作共享数据 2. //未完待续后面会继续更新