如何使用Swift 3制作图像裁剪器
我最近有一个项目,我必须按特定的宽高比裁剪图像,但找不到完整的教程,所以我认为我应该做一个。
我按照以下步骤划分了本教程,以便您轻松理解。
- 创建图像缩放和滚动。
- 计算图像视图内的图像帧。
- 计算相对于实际图像尺寸的裁剪区域框。
- 进行裁剪
创建图像缩放和滚动
让我们从创建一个ViewController开始。 因此,转到您的故事板文件,然后从XCode右下角的对象库中拖动一个新的ViewController。 现在将一个ScrollView拖到ViewController上,并将ScrollView的帧调整到ViewController的边缘,然后将ImageView拖到ScrollView下,并将ImageView的帧调整到ScrollView的边缘。 要添加所有缺少的约束,只需转到情节提要的右下角,然后单击“向所有视图添加缺少的约束”。
现在,可以通过ImageAsset在ImageView上设置图像,但是稍后在您的应用程序中,您可以从相机或照片库或任何其他来源获取图像并将其设置为ImageView。 还将内容模式更改为Aspect Fit。
现在,为ScrollView和ImageView创建出口,并设置scrollview的委托,最小缩放比例和最大缩放比例。
class ImageCropperViewController:UIViewController,UIScrollViewDelegate {
@IBOutlet var scrollView:UIScrollView!{
didSet {
scrollView.delegate =自我
scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 10.0
}
}
@IBOutlet var imageView:UIImageView!
}
最后,我们需要实现一个UIScrollViewDelegate函数,该函数将返回需要缩放的视图。 对于我们来说,我们需要返回ImageView。
func viewForZooming(在scrollView中:UIScrollView)-> UIView? {
返回imageView
}
计算图像视图内的图像帧
当ImageView的内容模式为Aspect Fit时,图像可能不会填满ImageView的所有空间,因此,ImageView内部的图像帧可能不等于其边界。 创建UIImageView的扩展,然后编写一个函数来计算ImageView中的图像帧。
扩展程序UIImageView {
func imageFrame()-> CGRect {
让imageViewSize = self.frame.size
警卫队让imageSize = self.image?.size else {返回CGRect.zero}
让imageRatio = imageSize.width / imageSize.height
让imageViewRatio = imageViewSize.width / imageViewSize.height
如果imageRatio <imageViewRatio {
让scaleFactor = imageViewSize.height / imageSize.height
设width = imageSize.width * scaleFactor
让topLeftX =(imageViewSize.width-width)* 0.5
返回CGRect(x:topLeftX,y:0,width:width,height:imageViewSize.height)
}其他{
让scalFactor = imageViewSize.width / imageSize.width
设高度= imageSize.height * scalFactor
让topLeftY =(imageViewSize.height-height)* 0.5
返回CGRect(x:0,y:topLeftY,width:imageViewSize.width,height:height)
}
}
}
计算相对于实际图像尺寸的裁剪区域框架
现在我们需要定义一个裁剪区域。 您可以将整个屏幕或特定区域设为裁剪区域。 要定义裁剪区域,请在ViewController中拖动另一个View,然后将其放置在与ScrollView相同的层次结构中。 向视图添加“前导”,“尾随”,“垂直居中”和“长宽比”约束。 您可以根据需要更改约束。 现在,我将“前导”,“尾随”和“垂直居中常数”设置为0,将纵横比常数设置为“ 16:9”。 还可以降低“视图”的Alpha值,以便用户可以查看它。
如果您运行该应用程序并进行检查,则可以看到您无法缩放我们刚刚放置的用于定义裁剪区域的视图。 因此,要克服此问题,请创建一个Custom UIView,它将把触摸传递到下面的视图。
CropAreaView类:UIView {
覆盖函数点(内部点:CGPoint,事件:UIEvent?)->布尔{
返回假
}
}
将情节提要中的“视图”类设置为我们刚刚创建的自定义类。
在屏幕上成功定义裁剪区域后,我们必须将该区域映射到实际图像。
首先,创建视图的出口。
@IBOutlet var cropAreaView:CropAreaView!
现在,定义一个计算变量,该变量将返回相对于实际图像的裁剪区域的帧。
var cropArea:CGRect {
得到{
让因子= imageView.image!.size.width / view.frame.width
让比例= 1 / scrollView.zoomScale
让imageFrame = imageView.imageFrame()
令x =(scrollView.contentOffset.x + cropAreaView.frame.origin.x-imageFrame.origin.x)*比例*因子
令y =(scrollView.contentOffset.y + cropAreaView.frame.origin.y-imageFrame.origin.y)*比例*因子
设width = cropAreaView.frame.size.width *比例*因子
设高度= cropAreaView.frame.size.height *比例*因子
返回CGRect(x:x,y:y,宽度:宽度,高度:高度)
}
}
执行裁剪
实际上,这将是以上所有步骤中最简单的任务。 在ViewController上拖动一个按钮,将触发裁剪。 确保按钮在层次结构上与ScrollView和CropView处于同一级别。 还添加底部空间和水平居中约束。
最后创建按钮的动作并裁剪图像。
@IBAction func crop(_ sender:UIButton){
让croppedCGImage = imageView.image?.cgImage?.cropping(收件人:cropArea)
让croppedImage = UIImage(cgImage:croppedCGImage!)
imageView.image =裁剪图像
}
如果运行应用程序并裁剪图像,则将成功裁剪图像,但是存在一个问题。 裁剪后的图像将以先前的缩放级别显示。 因此,要解决此问题,我们必须重置ScrollView的缩放级别。
scrollView.zoomScale = 1
就这样。 现在您有了croppedImage,可以根据需要使用它。 希望你喜欢! 😋谢谢!! 🙏
完整项目:https://github.com/aatish-rajkarnikar/ImageCropper
如果您想使Image Cropper像Instagram一样,我还有另一本有关如何使Image Cropper像Instagram的教程。