图像处理 图像切割
2015-10-13 15:51
267 查看
在很多时候我们需要对一张图片进行裁剪,尽管CALayer已经为我们提供了很多方便,可以轻易实现圆形,圆角矩形,甚至直角+圆角的矩形,然而在一些特殊情况下,需要对图片进行不规则形状(比如半个⭐️)裁剪的时候,就需要一些手段来进行图片处理了。
当然如果用CALayer来画path的话,任何形状都是可以画的,但是必须把每一个轮廓都写一遍,而描述这些轮廓,会随着图形复杂度而相应的繁琐,更糟糕的是,如果换一个形状,就要重新进行一次复杂的描述,那简直是噩梦。
所以在这里我们推荐一种简单的办法:Mask 切割
这个办法的原理很简单,需要先准备一张切割形状的非半透明图片,通过与被切割图片求交集的方式进行切割,得到的结果就是切割形状的图片了。比如你要把一幅图片切割成半⭐️形的,就准备一张半⭐️形状的mask图,图中需要有一个半⭐️的非透明部分,其余部分透明,然后把希望裁剪的图片以mask图作为模版裁剪,得到的就是想要的结果了.
+
=
来看看代码:
1.首先准备好原图
UIImage* rawImage = [UIImage imageNamed:@"photo.png”];
2.初始化绘图环境
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
3.将原图先画入内存中
[image drawInRect:CGRectMake(0,0, size.width, size.height)];
4.读取mask图片
UIImage* mask = [UIImage imageNamed:@"mask.png"];
5.(核心)将原图以mask为模版进行切割
[mask drawInRect:CGRectMake(0, 0, size.width, size.width)
blendMode:kCGBlendModeDestinationIn
alpha:1];
//此处的参数可分为source和destination,分别去共同部分和不同部分。
6.生成想要的结果图
UIImage* retImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return retImage;
ok,会了这招以后,接下来运用到实战当中,比如在QQ的多人聊天组头像(梅花状头像组),就可以通过这种方式来实现。
那么接下来可以看到,在实际情况中,主要是针对3,4,5,6人头像进行绘制。那么仔细观察就会发现,其实他们是用的同一个mask,只是根据不同的人数,各自旋转不同的角度,以及进行不同程度的缩放,最后组合而成。
以3个头像为例:
1.先计算出三个头像的分布
if (imageCount == 3) {
head_s = 26;
CGRect rcImage = CGRectMake((bg_width - head_s) / 2, (bg_height - head_s - 3), head_s, head_s);
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
rcImage = CGRectMake(0, 0, head_s, head_s);
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
rcImage = CGRectMake((bg_width - head_s), 0, head_s, head_s );
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
}
2.在确定三个头像的位置后,接下来确定各自的角度
for ( int j=0; j<imageCount; ++j ){
UIImage *image_inx = [imageArray objectAtIndex:j];
if (imageCount > 2 || j == 0) {
double angel = startAngel - 2 * j * M_PI / imageCount;
3.然后根据各自度数进行’月牙形’裁剪
image_inx = [self maskImageWithSize:image_inx angle:angel];
}
CGRect rcImage = [[rectArray objectAtIndex:j] CGRectValue];
CGContextDrawImage(context, rcImage, image_inx.CGImage);
}
4.最后将三幅图都画在一起便得到了一个梅花状的头像组。
当然如果用CALayer来画path的话,任何形状都是可以画的,但是必须把每一个轮廓都写一遍,而描述这些轮廓,会随着图形复杂度而相应的繁琐,更糟糕的是,如果换一个形状,就要重新进行一次复杂的描述,那简直是噩梦。
所以在这里我们推荐一种简单的办法:Mask 切割
这个办法的原理很简单,需要先准备一张切割形状的非半透明图片,通过与被切割图片求交集的方式进行切割,得到的结果就是切割形状的图片了。比如你要把一幅图片切割成半⭐️形的,就准备一张半⭐️形状的mask图,图中需要有一个半⭐️的非透明部分,其余部分透明,然后把希望裁剪的图片以mask图作为模版裁剪,得到的就是想要的结果了.
+
=
来看看代码:
1.首先准备好原图
UIImage* rawImage = [UIImage imageNamed:@"photo.png”];
2.初始化绘图环境
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
3.将原图先画入内存中
[image drawInRect:CGRectMake(0,0, size.width, size.height)];
4.读取mask图片
UIImage* mask = [UIImage imageNamed:@"mask.png"];
5.(核心)将原图以mask为模版进行切割
[mask drawInRect:CGRectMake(0, 0, size.width, size.width)
blendMode:kCGBlendModeDestinationIn
alpha:1];
//此处的参数可分为source和destination,分别去共同部分和不同部分。
6.生成想要的结果图
UIImage* retImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return retImage;
ok,会了这招以后,接下来运用到实战当中,比如在QQ的多人聊天组头像(梅花状头像组),就可以通过这种方式来实现。
那么接下来可以看到,在实际情况中,主要是针对3,4,5,6人头像进行绘制。那么仔细观察就会发现,其实他们是用的同一个mask,只是根据不同的人数,各自旋转不同的角度,以及进行不同程度的缩放,最后组合而成。
以3个头像为例:
1.先计算出三个头像的分布
if (imageCount == 3) {
head_s = 26;
CGRect rcImage = CGRectMake((bg_width - head_s) / 2, (bg_height - head_s - 3), head_s, head_s);
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
rcImage = CGRectMake(0, 0, head_s, head_s);
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
rcImage = CGRectMake((bg_width - head_s), 0, head_s, head_s );
[rectArray addObject:[NSValue valueWithCGRect:rcImage]];
}
2.在确定三个头像的位置后,接下来确定各自的角度
for ( int j=0; j<imageCount; ++j ){
UIImage *image_inx = [imageArray objectAtIndex:j];
if (imageCount > 2 || j == 0) {
double angel = startAngel - 2 * j * M_PI / imageCount;
3.然后根据各自度数进行’月牙形’裁剪
image_inx = [self maskImageWithSize:image_inx angle:angel];
}
CGRect rcImage = [[rectArray objectAtIndex:j] CGRectValue];
CGContextDrawImage(context, rcImage, image_inx.CGImage);
}
4.最后将三幅图都画在一起便得到了一个梅花状的头像组。
相关文章推荐
- nyoj 228 士兵杀死(五岁以下儿童)【树状数组】
- python自动化执行脚本
- 微信浏览器缓存问题
- HBase 与 OceanBase
- vijosP1092 全排列
- 首先,要申明一点,过去与现在,电影的字幕都不是问题。并且,网络如此自由,未来也不是问题。只是分享的平台不会一家独大,分享的途径方式也会多种多样。
- jquery easyui 输入框 禁止输入负数 设置属性data-options="min:0,required:true"
- UITabBarController用法
- 搭建Python开发环境
- Java中部分关键字
- struts2学习04——数据封装核心机制
- centos7 初始化
- android studio 1.4 --2015年10月13日从官网下载,提供给不能上官网的孩子
- onAttachedToWindow()在整个Activity生命周期的位置及使用 .
- IOS开发之格式化日期时间
- 毛玻璃效果
- Java 异常笔试题
- lintcode 容易题:Flip Bits 将整数A转换为B
- Nignx 连接tomcat时会话粘性问题分析
- Android Studio 发生 Couldn't load jpush175 from loader dalvik.system.PathClassLoader 错误