Разделим проблему на две части:
Первая часть - интересная часть, поэтому давайте попробуем ее. (Вторая часть окажется тривиальной.)
Вот исходное изображение, которое я буду использовать:
Это изображение 1000x611. Вот как он выглядит уменьшенным (но имейте в виду, что я буду использовать оригинальное изображение ):
Мое изображение, однако, будет 139x182 и будет установлено в Aspect Fill. Когда он отображает изображение, он выглядит следующим образом:
Проблема, которую мы хотим решить: какая часть оригинала изображение отображается в моем представлении изображения, если для моего представления изображения установлено значение «Аспект заливки»?
Здесь мы идем. Предположим, что iv
- это вид изображения:
let imsize = iv.image!.size
let ivsize = iv.bounds.size
var scale : CGFloat = ivsize.width / imsize.width
if imsize.height * scale < ivsize.height {
scale = ivsize.height / imsize.height
}
let croppedImsize = CGSize(width:ivsize.width/scale, height:ivsize.height/scale)
let croppedImrect =
CGRect(origin: CGPoint(x: (imsize.width-croppedImsize.width)/2.0,
y: (imsize.height-croppedImsize.height)/2.0),
size: croppedImsize)
Итак, теперь мы решили проблему: croppedImrect
- это область исходного изображения , которая отображается в изображение. Давайте продолжим использовать наши знания, фактически обрезая изображение на новое изображение, соответствующее тому, что показано на изображении:
let r = UIGraphicsImageRenderer(size:croppedImsize)
let croppedIm = r.image { _ in
iv.image!.draw(at: CGPoint(x:-croppedImrect.origin.x, y:-croppedImrect.origin.y))
}
Результатом является это изображение (игнорируйте серая рамка):
Но вот, вот правильный ответ! Я извлек из исходного изображения ровно область, изображенную внутри изображения.
Итак, теперь у вас есть вся необходимая информация. croppedIm
- это UIImage, фактически отображаемый в обрезанной области изображения. scale
- масштаб между изображением и этим изображением. Поэтому вы можете легко решить проблему, которую вы изначально предложили! Учитывая любой прямоугольник, наложенный на изображение, в координатах границ изображения, вы просто применяете масштаб (т. Е. Делите все четыре его атрибута на scale
) - и теперь у вас есть тот же прямоугольник, что и часть croppedIm
.
(Обратите внимание, что нам действительно действительно нужно обрезать исходное изображение, чтобы получить croppedIm
; в действительности было достаточно знать , как для выполнения этой обрезки. Важной информацией является scale
вместе с origin
из croppedImRect
, учитывая эту информацию, вы можете взять прямоугольник, наложенный на изображение, масштабировать его, и смещать его , чтобы получить желаемый прямоугольник исходного изображения.)
EDIT Я добавил небольшой скринкаст, чтобы показать, что мой подход работает как доказательство концепции:
EDIT Также создан загружаемый пример проекта здесь:
Но обратите внимание, что я не могу гарантировать, что URL-адрес будет длиться вечно, поэтому, пожалуйста, прочитайте приведенное выше обсуждение, чтобы понять используемый подход.
croppedIm
и примените аспект. Так почему бы просто не сделать это? Это то, что я имел в виду, сводя его к ранее разрешенной проблеме. – matt 1 May 2017 в 18:58