如何像Instagram第1部分一样裁剪图像

在发布任何内容之前将图像裁剪为正方形或放大/缩小是使用Instagram的用户的常见操作。 这似乎是一个很容易的任务。 但是有些人可能会感到困惑,为什么裁剪后的图像返回错误的尺寸或方向。 本教程将向您展示如何处理裁剪问题。

本教程基于iOS环境,因此在Android或其他OS上可能会变得不正确(因为图像设置可能有所不同)。

图像大小可以分为3种类型:

  • 宽度=高度
  • 宽度>高度
  • 宽<高

不要理会如何在滚动视图中将图像居中。 这是一个小技巧,将出现在另一篇文章中。 在这里,假设我们有一个可缩放和可拖动的滚动视图,其中包含一个图像视图。 我们可以缩放图像或将其拖动以仅显示图像的特定区域。 之后,我们可能只想在Instagram上显示该区域(也许我们想隐藏一些东西,可能是一头凌乱的头发哈哈)。 因此,这是裁剪图像的时间。

要裁剪图像的区域,我们需要知道图像中该区域的偏移量和大小。 在这里,我们需要知道图像而不是屏幕上的实际偏移量和大小。 为什么? 因为当在屏幕上显示时,图像将按比例缩小以适合屏幕尺寸。 例如,在上图中,屏幕尺寸(此处为可缩放滚动视图)为300 * 300,而图像的分辨率为3000 * 2000。 因此,我们需要将图像缩放到300 * 200的大小,以使其适合屏幕(以便于查看)。 我们称imageScale为图像需要缩放以适合屏幕的值。 计算方法如下:

imageScale = image.size.height <= image.size.width? image.size.width / scrollView.size.width:image.size.height / scrollView.size.height

为什么存在这个公式? 当缩放以适合滚动视图时,图像的一侧必须适合滚动视图。 这意味着,如果image.size.height <= image.size.width,图像的宽度必须适合屏幕,而高度将小于屏幕,反之亦然。

所以现在我们有了一个名为imageScale的变量。 我们还有scrollView的zoomScale,它指示我们放大/缩小图像的数量。

在此图像中,我有一点放大并向上滚动图像。 因此,现在图像的高度超过了屏幕的大小。 我们很容易得到scrollView的偏移量。 但是,由于它不是图像中的实际偏移量,因此无法使用它进行裁剪。 实际偏移量计算如下:

actualOffset = scrollView.offset * imageScale / zoomScale

现在我们有了实际的偏移量。 我们只需要裁剪即可。 为了获得实际的尺寸,我们需要分为3种不同的情况:

  • image.width = image.height:

在这种情况下,我们只需要计算实际宽度或实际高度。

actualWidth = image.width / zoomScale

ActualHeight =实际宽度

这是因为在zoomScale = 1.0时,图像将填满整个屏幕。 当zoomScale增大时,屏幕上可见的图像区域将减小。 我们只需要将图像的原始大小除以zoomScale即可获得显示在屏幕上的区域大小。

  • image.width> image.height:

在这种情况下,假设我们具有heightOnScreen = imageView.height。 这里有2个小案例:

+ image.height未填满屏幕:heightOnScreen <scrollView.height

+ image.height超出了屏幕:heightOnScreen> = scrollView.height

在这里,visibleHeight = min(heightOnScreen,scrollView.height)

我们很容易计算出ActualHeight和ActualWidth:

actualHeight = visibleHeight * imageScale / zoomScale

actualWidth = image.width / zoomScale

  • image.width <image.height:计算与上述相同,只是将width更改为height,反之亦然。

因此,现在有了可以用来裁剪图像的actualOffset和actualSize。 但是,在某些情况下,此公式不正确。 这是因为我们没有考虑图像的方向。 这个问题将在下一篇文章中介绍。