Как масштабировать до желаемого размера в пикселях, используя af_imageAspectScaled - PullRequest
0 голосов
/ 01 мая 2019

Я использую AlamoFireImage, чтобы обрезать изображение профиля пользователя перед отправкой на сервер. Наш сервер имеет некоторые ограничения, и мы не можем отправлять изображения размером более 640x640.

Я использую функцию расширения af_imageAspectScaled UIImage, например:

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

Я ожидал, что это обрезает image до изображения 320 на 320 пикселей. Однако я обнаружил, что выходное изображение сохраняется как изображение 640x640px с масштабом 2.0. Следующий 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)
    }  
  }
}

Я запускаю это на симуляторе iPhone Xr на Xcode 10.2.

Исходное изображение имеет размер 1280 на 960 точек и масштаб 1, что эквивалентно 1280 на 960 пикселей. Обрезанное изображение имеет размер 320 на 320 точек и масштаб 2, что эквивалентно 640 на 640 пикселей.

Почему шкала установлена ​​на 2? Могу ли я это изменить? Как создать изображение размером 320 на 320 пикселей независимо от масштаба и устройства?

1 Ответ

0 голосов
/ 01 мая 2019

Ну, проверяя исходный код для метода af_imageAspectScaled Я нашел следующий код для генерации фактического масштабированного изображения:

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

Параметр со значением 0.0 на UIGraphicsBeginImageContextWithOptions сообщаетметод использования масштабного коэффициента основного экрана для определения размера изображения.

Я попытался установить это значение равным 1,0, и при запуске моего теста af_imageAspectScaled сгенерировал изображение с нужными размерами, которые я хотел.

Здесь есть таблица, показывающая все разрешения устройств 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
  )
)

Я отправил запрос на извлечение AlamofireImage с предложением добавить параметр scale в функции af_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.
...