如何使用Swift 3制作图像裁剪器

我最近有一个项目,我必须按特定的宽高比裁剪图像,但找不到完整的教程,所以我认为我应该做一个。

我按照以下步骤划分了本教程,以便您轻松理解。

  1. 创建图像缩放和滚动。
  2. 计算图像视图内的图像帧。
  3. 计算相对于实际图像尺寸的裁剪区域框。
  4. 进行裁剪

创建图像缩放和滚动

让我们从创建一个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的教程。

Interesting Posts