如何使用af_imageAspectScaled缩放至所需的像素大小

时间:2019-05-01 00:36:16

标签: ios swift alamofireimage

我正在使用AlamoFireImage裁剪用户个人资料图片,然后再将其发送到服务器。我们的服务器有一些限制,我们不能发送大于640x640的图像。

我正在使用af_imageAspectScaled UIImage扩展函数,如下所示:

let croppedImage = image.af_imageAspectScaled(
  toFill: CGSize(
    width: 320,
    height: 320
  )
)

我期望它可以将image裁剪为320px x 320px的图像。但是我发现输出图像被保存为比例为2.0的640x640px图像。以下XCTest显示了这一点:

class UIImageTests: XCTestCase {
  func testAfImageAspectScaled() {
    if let image = UIImage(
      named: "ipad_mini2_photo_1.JPG",
      in: Bundle(for: type(of: self)),
      compatibleWith: nil
    ) {
      print (image.scale) // prints 1.0
      print (image.size)  // prints (1280.0, 960.0)

      let croppedImage = image.af_imageAspectScaled(
        toFill: CGSize(
          width: 320,
          height: 320
        )
      )

      print (croppedImage.scale) // prints 2.0
      print (croppedImage.size)  // prints (320.0, 320.0)
    }  
  }
}

我正在Xcode 10.2的iPhone Xr模拟器上运行它。

原始图像为1280 x 960点,缩放比例为1,相当于1280 x 960像素。裁剪后的图像为320 x 320点,缩放比例为2,相当于640 x 640像素。

为什么小数位数设置为2?我可以改变吗?如何生成独立于比例尺和设备的320 x 320像素的图像?

1 个答案:

答案 0 :(得分:0)

好吧,检查source code for the af_imageAspectScaled method时发现了以下代码,用于生成实际的缩放图像:

UIGraphicsBeginImageContextWithOptions(size, af_isOpaque, 0.0)
draw(in: CGRect(origin: origin, size: scaledSize))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext() ?? self
UIGraphicsEndImageContext()

UIGraphicsBeginImageContextWithOptions上的值为0.0的参数告诉该方法使用主屏幕比例因子来定义图像大小。

我尝试将其设置为1.0,并且在运行测试用例时,af_imageAspectScaled生成了具有所需尺寸的图像。

Here中有一个表格,显示所有iOS设备的分辨率。我的应用正在为比例因子为2.0的所有设备发送适当大小的图像,但是一些设备的比例因子为3.0。对于那些应用程序无法正常工作。

不幸的是,似乎我想使用af_imageAspectScaled时,必须像这样设置缩放后的尺寸时,将所需的最终尺寸除以设备的尺寸:

let scale = UIScreen.main.scale

let croppedImage = image.af_imageAspectScaled(
  toFill: CGSize(
    width: 320/scale,
    height: 320/scale
  )
)

I've sent a pull request to AlamofireImage建议向功能scaleaf_imageAspectScaled(toFill:)af_imageAspectScaled(toFit:)添加参数af_imageScaled(to:)。如果他们接受,则上面的代码应变为:

// this is not valid with Alamofire 4.0.0 yet! waiting for my pull request to
// be accepted
let croppedImage = image.af_imageAspectScaled(
  toFill: CGSize(
    width: 320,
    height: 320
  ),
  scale: 1.0
)
// croppedImage would be a 320px by 320px image, regardless of the device type.