Обрезание изображения в iOS [дубликат]

использовать функцию die ()

or die(mysql_error());

3
задан zic10 2 May 2017 в 16:46
поделиться

1 ответ

Разделим проблему на две части:

  1. Учитывая размер UIImageView и размер его UIImage, если режим содержимого UIImageView - это Aspect Fill, то какая часть UIImage который вписывается в UIImageView? Фактически нам нужно обрезать исходное изображение , чтобы оно соответствовало тому, что фактически отображает UIImageView.
  2. Учитывая произвольный прямоугольник внутри UIImageView, какая часть обрезанного image (полученный в части 1) соответствует ли это?

Первая часть - интересная часть, поэтому давайте попробуем ее. (Вторая часть окажется тривиальной.)

Вот исходное изображение, которое я буду использовать:

https://static1.squarespace.com/static / 54e8ba93e4b07c3f655b452e / t / 56c2a04520c64707756f4267 / 1455596221531 /

Это изображение 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 Также создан загружаемый пример проекта здесь:

https://github.com/mattneub/Programming-iOS-Book-Examples / BLOB / 39cc800d18aa484d17c26ffcbab8bbe51c614573 / bk2ch02p058cropImageView / Кроппер / ViewController .swift

Но обратите внимание, что я не могу гарантировать, что URL-адрес будет длиться вечно, поэтому, пожалуйста, прочитайте приведенное выше обсуждение, чтобы понять используемый подход.

7
ответ дан matt 17 August 2018 в 12:14
поделиться
  • 1
    Я понимаю, что вы разместили, но не могли бы вы рассказать о том, что вы имели в виду "просто примените масштаб, и теперь у вас есть тот же прямоугольник, что и часть обрезанногоIm". Мое представление об уроках является динамическим по размеру и положению и даже с использованием обрезки и использования моей функции, которую я поставил выше урожая, все еще выключен, и я не совсем уверен, почему. – zic10 1 May 2017 в 18:48
  • 2
    Если ваш код работает для соответствия аспекту, он будет работать, если вы замените croppedIm и примените аспект. Так почему бы просто не сделать это? Это то, что я имел в виду, сводя его к ранее разрешенной проблеме. – matt 1 May 2017 в 18:58
  • 3
    Да, я понимаю, что вы говорите. Я собираюсь обновить свой оригинальный вопрос с кодом, включая ваше решение для контекста. – zic10 1 May 2017 в 18:59
  • 4
    Я добавил небольшой скринкаст, чтобы показать, что мой подход работает правильно, чтобы на самом деле обрезать изображение на назначенный прямоугольник. – matt 2 May 2017 в 01:02
  • 5
    Обновлено мое сообщение с работоспособным решением и демонстрацией функциональности gif. – zic10 2 May 2017 в 16:47