iOS 图片剪裁(附demo下载)
文章目录
- Demo 说明
- 基本功能描述
- 剪裁界面布局
- 用贝塞尔绘制半透明蒙版
- 拖拽捏合图片
- 考虑事项:
- 捏合后,图片宽、高,小于裁剪框的宽高
- 移动后、缩小后,图片四角不在裁剪框内;
- 剪裁方法
Demo下载地址:http://download.csdn.net/detail/lovechris00/9873031
Demo 说明
- 本代码参考 杨淑园 的 YSHYClipViewController;
- 可裁剪圆形、正方形、长方形(自己设置尺寸);
- 界面都搭建好,拿来即用;
由于mardown处理图片尺寸很麻烦,所以效果图见文章最下方。如有问题,欢迎反馈留言~!
基本功能描述
- 进入剪裁界面,图片适配剪裁框宽高。(根据尺寸比例,让图片的宽等于剪裁框宽度,或者高与之相等)。
- 为图片添加手势,和手势的代理。根据拖拽、捏合手势,来处理图片的放大、移动。
- 拖拽、捏合时,让图片处于裁剪范围内。暂时没有做旋转。
- 点击确定时,根据图片比例和位置,复制图片内容到画布,并输出画布。
- 通过代理,输出结果到调用的控制器。
剪裁界面布局
用贝塞尔绘制半透明蒙版
#pragma mark - 绘制裁剪框
-(void)drawClipPath
{UIBezierPath *path= [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, self.view.mj_w, self.view.mj_h)];CAShapeLayer *layer = [CAShapeLayer layer];UIBezierPath *clipPath;if (self.clipType == SQUARECLIP) {//方形clipPath = [UIBezierPath bezierPathWithRect:self.clipFrame];}else{clipPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.clipFrame), CGRectGetMidY(self.clipFrame)) radius:_clipW * 0.5 startAngle:0 endAngle:2*M_PI clockwise:NO];}[path appendPath:clipPath];[path setUsesEvenOddFillRule:YES];layer.path = path.CGPath;layer.fillRule = kCAFillRuleEvenOdd;layer.fillColor = [[UIColor blackColor] CGColor];layer.opacity = 0.5;[_overView.layer addSublayer:layer];//添加白线CAShapeLayer *shapeLayer = [CAShapeLayer layer];shapeLayer.frame = _overView.bounds;shapeLayer.path = clipPath.CGPath;shapeLayer.fillColor = [UIColor clearColor].CGColor;shapeLayer.lineWidth = 1.0f;shapeLayer.strokeColor = [UIColor whiteColor].CGColor;[_overView.layer addSublayer:shapeLayer];
}
拖拽捏合图片
根据拖拽中 [panGesture translationInView:view.superview];改变图片位置
根据捏合中的 pinGesture.scale 改变图片大小。
考虑事项:
捏合后,图片宽、高,小于裁剪框的宽高
处理方式:如果图片宽度imgW 小于裁剪框的宽 clipW,则让图片 imgW = clipW; 如果处理后 图片高度imgH 小于裁剪框高度 clipH , 则让 imgH = clipH。
针对不同尺寸的裁剪框,我们要让图片宽高中的最小项,大于裁剪框宽高中的最大项。所以可以根据宽高比来方便判断。
重新设置尺寸的方法如下:
#pragma mark -- 处理图片大小
-(CGSize )handleScale
{CGFloat oriRate = _image.size.width / _image.size.height;CGFloat clipRate = _clipW / _clipH;CGSize resultSize;if (oriRate > clipRate) {resultSize.height = _clipH;resultSize.width = oriRate * _clipH;}else{resultSize.width = _clipW;resultSize.height = _clipW / oriRate;}return resultSize;
}
移动后、缩小后,图片四角不在裁剪框内;
经过上述操作,图片尺寸不会小于裁剪框尺寸。所以只需要判断四角的x,y值。
如果左上角在框内,则让x = clipX,同理亦然。具体代码如下:
#pragma mark -- 缩放结束后 确保图片在裁剪框内
-(CGRect )handlePosition:(UIView *)view
{// 图片.top < 裁剪框.topif(view.frame.origin.y > self.clipFrame.origin.y){CGRect viewFrame = view.frame;viewFrame.origin.y = self.clipFrame.origin.y;view.frame = viewFrame;}// 图片.left < 裁剪框.leftif(view.frame.origin.x > self.clipFrame.origin.x){CGRect viewFrame = view.frame;viewFrame.origin.x = self.clipFrame.origin.x;view.frame = viewFrame;}// 图片.right < 裁剪框.rightif(CGRectGetMaxX(view.frame)< CGRectGetMaxX(self.clipFrame)){CGFloat right =CGRectGetMaxX(view.frame);CGRect viewFrame = view.frame;CGFloat space = CGRectGetMaxX(self.clipFrame) - right;viewFrame.origin.x+=space;view.frame = viewFrame;}// 图片.bottom < 裁剪框.bottomif(CGRectGetMaxY(view.frame) < CGRectGetMaxY(self.clipFrame)){CGRect viewFrame = view.frame;CGFloat space = CGRectGetMaxY(self.clipFrame) - (CGRectGetMaxY(view.frame));viewFrame.origin.y +=space;view.frame = viewFrame;}return view.frame;
}
剪裁方法
#pragma mark - 裁剪获取图片
-(UIImage *)getClippedImage
{CGFloat rationScale = (_imageView.mj_w /_image.size.width);CGFloat origX = (self.clipFrame.origin.x - _imageView.frame.origin.x) / rationScale;CGFloat origY = (self.clipFrame.origin.y - _imageView.frame.origin.y) / rationScale;CGFloat oriWidth = _clipW / rationScale;CGFloat oriHeight = _clipH / rationScale;CGRect myRect = CGRectMake(origX, origY, oriWidth, oriHeight);CGImageRef imageRef = CGImageCreateWithImageInRect(_image.CGImage, myRect);UIGraphicsBeginImageContext(myRect.size);CGContextRef context = UIGraphicsGetCurrentContext();CGContextDrawImage(context, myRect, imageRef);UIImage * clipImage = [UIImage imageWithCGImage:imageRef];UIGraphicsEndImageContext();if(self.clipType == CIRCULARCLIP){return [self clipCircularImage:clipImage];}return clipImage;
}#pragma mark -- 裁剪图片为圆形效果
-(UIImage *)clipCircularImage:(UIImage *)image
{CGFloat arcCenterX = image.size.width/ 2;CGFloat arcCenterY = image.size.height / 2;UIGraphicsBeginImageContext(image.size);CGContextRef context = UIGraphicsGetCurrentContext();CGContextBeginPath(context);CGContextAddArc(context, arcCenterX , arcCenterY, image.size.width/ 2 , 0.0, 2*M_PI, NO);CGContextClip(context);CGRect myRect = CGRectMake(0 , 0, image.size.width , image.size.height);[image drawInRect:myRect];UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();return newImage;
}
效果如下:
iOS 图片剪裁(附demo下载)相关推荐
- Winform中实现对照片添加文字和图片水印(附代码下载)
场景 项目运行效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建 ...
- 微信分享接口示例(设置标题、缩略图、连接、描述),附demo下载
前几天因为项目所需要实现微信分享接口,在网上搜了一大堆,实现办法大致分为两种,第一:在body之后加一个img标签并且设置display:none,这种方法感觉不科学所以我没有测试过.第二:使用微信的 ...
- 微信小程序开源项目库集合,附demo下载
查看全文 http://www.taodudu.cc/news/show-5534229.html 相关文章: android tv二级菜单,android TV开发:弹出菜单实现 [原创]移动端底部 ...
- C#也能PS图片,还能为网站Ajax上传图片同时生成微缩图(附Demo)
C#也能PS图片,还能为网站Ajax上传图片同时生成微缩图(附Demo) 本文旨在与各位朋友们分享我是如何在项目中用C# "ps图片" 为网站生成同比例微缩图的解决方案.如有不足之 ...
- 微信小程序开发之文件上传下载应用场景(附Demo源码)
微信小程序开发之文件上传下载应用场景(附Demo源码),Demo为小相册应用,源码在附件中,本示例需要腾讯云支持. http://www.henkuai.com/forum.php?mod=viewt ...
- iOS WKWebView JS原生交互之JS调用OC(附demo)
Demo下载地址:https://github.com/msbaby520/WKWebViewJSCallOC 2019.02.26 更新 注意: iOS12起不再支持UIWebView,请采用WKW ...
- ios 裁剪框大小_iOS实现裁剪框和图片剪裁功能
这篇文章主要为大家详细介绍了iOS实现裁剪框和图片剪裁功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下图片处理中经常用的图片剪裁,就是通过剪裁框确定图片剪裁的区域,然后剪去该区域的图片,今天实现 ...
- ADO.NET Entity Framework 入门示例向导(附Demo程序下载)
ADO.NET Entity Framework 入门示例向导(附Demo程序下载) ADO.NET Entity Framework 是.Net Framework 3.5 SP1 引入的实体框架, ...
- iOS设计模式四部曲(二) 结构型模式 内附Demo
本篇是四部曲的第二篇,第一篇请点这里iOS设计模式四部曲(一):创建型模式 内附Demo,关于设计模式强烈推荐图书<Head First设计模式>以及<研磨设计模式>.由于个人 ...
最新文章
- HubbleDotNet 简介 (转)
- SQL SERVER中的三种获得自增长ID的方法
- win10安装Navicat 12 for MySQL
- 自动驾驶科普:一辆无人车到底是怎样工作的?
- git 更新_[技术分享T.191212]GitLab使用方法及git命令常见问题(不断更新)
- DMA及cache一致性的学习心得
- Tensorflow 入门手册(代码与原理释义)
- 安卓学习笔记28:文件流操作
- c++中的new_面试中常见的C语言与C++区别的问题
- 间接寻址与寄存器寻址,基址寻址与变址寻址
- java开发高薪工程师,Java开发工程师如何获得高薪
- oa处理会签流程图_深入剖析OA办公系统的流程管理方案
- Gvim开发环境配置笔记--Windows篇(转)
- 研发管理进阶:边怼人边改进
- เล่น บาคาร่ารับสิทธิประโยชน์มากมาย
- iPhone 11依然坚挺的原因是什么?
- RabbitMQ用户管理界面各个标签的解释,使用图片标注
- 虚拟机CentOS7磁盘分区表故障 无法启动
- Java8中文件转Base64和Base64转文件
- 十大排序算法(C语言代码)