iOS中的图像裁剪视图– Bassel Ezzeddine
在本教程中,我们将逐步在iOS中创建图像裁剪视图。 这是最后的样子:
首先,创建一个带有情节提要的空Xcode项目:
然后将具有自动布局约束的UIScrollView和裁剪按钮添加到情节提要中,如下所示:
之后,将UIImageView添加到具有自动布局约束的scrollview中,如下所示:
这将使我们能够放大和缩小图像,在接下来的步骤中将用于裁剪图像。
我们添加的约束对于图像视图填充滚动视图的所有内容很重要。
另外,我们应该将imageview的内容模式设置为AspectFit,这样我们的图像就不会被拉伸或变形。
接下来,拖动一个UIView并将其添加到具有自动布局约束的scrollview内,如下所示:
该视图将成为我们的作物视图。
在此非常重要的是,我们相对于主视图而不是相对于滚动视图或图像视图设置此裁剪视图的约束(后移,前导和居中Y)。 原因是使我们的裁剪视图始终固定在屏幕中间,同时缩放和移动其后面的图像。
现在,将scrollview,imageview和crop视图的出口连接到ViewController类和一些属性,如下所示:
我们设置滚动视图的最小和最大缩放比例属性,以限制放大和缩小。
此外,我们设置了裁剪视图的一些图层属性以配置其外观。
我们还应该通过返回其imageView实现其方法viewForZooming来实现UIScrollViewDelegate的要求,该方法是需要具有缩放功能的视图:
运行应用程序,它应该看起来像这样:
您应该能够放大和缩小,并将裁切视图放置在图像上的任何位置。
现在,我们需要使用“ cropImage”方法创建一个名为ImageCropHandler的新结构,该结构将根据定义的裁剪区域来裁剪UIImage:
该方法的代码直接从CGImage裁剪方法的Apple开发人员文档中复制:
https://developer.apple.com/documentation/coregraphics/cgimage/1454683-cropping
运作方式如下:
首先,我们计算输入图像的尺寸相对于imageView尺寸的比例(处理大于imageView的图像是必需的)。 然后,我们使用此比例来调整输入裁剪矩形的大小。
之后,我们使用此裁剪矩形作为参数调用CGImage的裁剪方法,然后得到其输出,即裁剪后的图像。
最后,我们将生成的裁剪后的CGImage投射到UIImage中,然后将其返回。
现在,我们创建裁剪按钮的IBAction方法,该方法将执行图像裁剪算法。
我们之前创建的cropImage方法采用四个参数:
- inputImage:由我们的imageView显示的图像
- cropRect:代表我们作物面积的矩形,其位置应相对于所显示的图像
- imageViewWidth:我们的imageView的宽度
- imageViewHeight:我们的imageView的高度
除了需要计算的cropRect以外,所有这些参数都准备好传递。
我们已经有了cropRect的宽度和高度,这与我们的crop视图的宽度和高度完全相同。 但是,cropRect的X和Y与我们的作物视图的X和Y不相等,因为它们应针对imageView内部的图像进行计算。 查看如何使用下图计算它们:
如此简单:
- X(cropRect)= X(CropView)– X(图像)
- Y(cropRect)= Y(作物视图)– Y(图像)
但是,为什么我们针对图像的位置而不是imageView进行计算呢?
原因是因为我们使用的是imageView的AspectFit属性,所以图像位置可能与imageView的位置不同(如果图像没有像本项目中的个人资料照片那样充满所有imageView,那么我们需要一种方法来获取scrollView中的实际图像位置。
我创建了一个UIImageView帮助器方法,该方法可为我们计算实际拟合图像的矩形,并包含我们需要的位置:
现在回到我们的ViewController中的裁剪IBAction,是时候进行裁剪了:
我们创建cropRect,将其传递给cropImage,在imageView上显示最终的裁剪图像,然后最终缩小到默认缩放比例:
完成了!
感谢您的阅读,希望您喜欢本教程🙂
您可以在GitHub上找到完整的代码:
https://github.com/BasselEzzeddine/PhotoCrop
- 从iOS的Grasshopper到QuickPreview:使用USDZ文件格式,第1部分
- 我如何添加一个ActivityItem到UIActivityViewController中的上层活动栏?
- Xcode的uitesting:staticTexts开始
- 即使在返回视图之后,委托方法也会被多次调用
- 通过JNLP使用Jenkins时,iOStesting不会在模拟器上运行
- IOS 8.3中的UIDatePicker内存泄漏
- 我如何添加跨越两个视图的渐变?
- Xcode 7:'supportedInterfaceOrientations'实现中的返回types冲突:'UIInterfaceOrientationMask'vs'NSUInteger'
- 扫描设备在LANnetworking中的方式