文章目录

    • 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下载)相关推荐

  1. Winform中实现对照片添加文字和图片水印(附代码下载)

    场景 项目运行效果 注: 博客主页: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 获取编程相关电子书.教程推送与免费下载. 实现 新建 ...

  2. 微信分享接口示例(设置标题、缩略图、连接、描述),附demo下载

    前几天因为项目所需要实现微信分享接口,在网上搜了一大堆,实现办法大致分为两种,第一:在body之后加一个img标签并且设置display:none,这种方法感觉不科学所以我没有测试过.第二:使用微信的 ...

  3. 微信小程序开源项目库集合,附demo下载

    查看全文 http://www.taodudu.cc/news/show-5534229.html 相关文章: android tv二级菜单,android TV开发:弹出菜单实现 [原创]移动端底部 ...

  4. C#也能PS图片,还能为网站Ajax上传图片同时生成微缩图(附Demo)

    C#也能PS图片,还能为网站Ajax上传图片同时生成微缩图(附Demo) 本文旨在与各位朋友们分享我是如何在项目中用C# "ps图片" 为网站生成同比例微缩图的解决方案.如有不足之 ...

  5. 微信小程序开发之文件上传下载应用场景(附Demo源码)

    微信小程序开发之文件上传下载应用场景(附Demo源码),Demo为小相册应用,源码在附件中,本示例需要腾讯云支持. http://www.henkuai.com/forum.php?mod=viewt ...

  6. iOS WKWebView JS原生交互之JS调用OC(附demo)

    Demo下载地址:https://github.com/msbaby520/WKWebViewJSCallOC 2019.02.26 更新 注意: iOS12起不再支持UIWebView,请采用WKW ...

  7. ios 裁剪框大小_iOS实现裁剪框和图片剪裁功能

    这篇文章主要为大家详细介绍了iOS实现裁剪框和图片剪裁功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下图片处理中经常用的图片剪裁,就是通过剪裁框确定图片剪裁的区域,然后剪去该区域的图片,今天实现 ...

  8. ADO.NET Entity Framework 入门示例向导(附Demo程序下载)

    ADO.NET Entity Framework 入门示例向导(附Demo程序下载) ADO.NET Entity Framework 是.Net Framework 3.5 SP1 引入的实体框架, ...

  9. iOS设计模式四部曲(二) 结构型模式 内附Demo

    本篇是四部曲的第二篇,第一篇请点这里iOS设计模式四部曲(一):创建型模式 内附Demo,关于设计模式强烈推荐图书<Head First设计模式>以及<研磨设计模式>.由于个人 ...

最新文章

  1. HubbleDotNet 简介 (转)
  2. SQL SERVER中的三种获得自增长ID的方法
  3. win10安装Navicat 12 for MySQL
  4. 自动驾驶科普:一辆无人车到底是怎样工作的?
  5. git 更新_[技术分享T.191212]GitLab使用方法及git命令常见问题(不断更新)
  6. DMA及cache一致性的学习心得
  7. Tensorflow 入门手册(代码与原理释义)
  8. 安卓学习笔记28:文件流操作
  9. c++中的new_面试中常见的C语言与C++区别的问题
  10. 间接寻址与寄存器寻址,基址寻址与变址寻址
  11. java开发高薪工程师,Java开发工程师如何获得高薪
  12. oa处理会签流程图_深入剖析OA办公系统的流程管理方案
  13. Gvim开发环境配置笔记--Windows篇(转)
  14. 研发管理进阶:边怼人边改进
  15. เล่น บาคาร่ารับสิทธิประโยชน์มากมาย
  16. iPhone 11依然坚挺的原因是什么?
  17. RabbitMQ用户管理界面各个标签的解释,使用图片标注
  18. 虚拟机CentOS7磁盘分区表故障 无法启动
  19. Java8中文件转Base64和Base64转文件
  20. 十大排序算法(C语言代码)

热门文章

  1. 《抽样技术》期末复习
  2. 分享一次光电可控硅的误用
  3. anacoda里面安装包显示失败_Photoshop解决安装失败!怎么办?!!!
  4. weblogic乱码问题解决
  5. drupal安装教程mysql_Drupal7安装完整教程
  6. PV、EV、AC、BAC、EAC、ETC
  7. MIS/MRP/ERP/OA/BPM/CMS等概念解析
  8. PDF的页面设置工具在哪里?如何使用并调整PDF页面?
  9. ros wiki learning
  10. 如何解密PDF文件?这些解密方法快来收藏