Я пытаюсь реплицировать функцию Instagram, где у вас есть изображение, и вы можете добавить наклейки (другие изображения), а затем сохранить их.
Итак, на UIImageView
, который содержит мое изображение, я добавляю к нему наклейку (другой UIImageView
) в качестве подзаголовка, расположенную в центре родительского UIImageView
.
Чтобы переместить наклейку вокруг изображения, я делаю это с помощью CGAffineTransform
(я не перемещаю центр UIImageView
). Я также применяю CGAffineTransform
для поворота и масштабирования стикера.
Чтобы сохранить изображение с помощью наклеек, я использую CGContext
следующим образом:
extension UIImage {
func merge2(in rect: CGRect, with imageTuples: [(image: UIImage, viewSize: CGSize, transform: CGAffineTransform)]) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
draw(in: CGRect(size: size), blendMode: .normal, alpha: 1)
// Those multiplicators are used to properly scale the transform of each sub image as the parent image (self) might be bigger than its view bounds, same goes for the subviews
let xMultiplicator = size.width / rect.width
let yMultiplicator = size.height / rect.height
for imageTuple in imageTuples {
let size = CGSize(width: imageTuple.viewSize.width * xMultiplicator, height: imageTuple.viewSize.height * yMultiplicator)
let center = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
let areaRect = CGRect(center: center, size: size)
context.saveGState()
let transform = imageTuple.transform
context.translateBy(x: center.x, y: center.y)
context.concatenate(transform)
context.translateBy(x: -center.x, y: -center.y)
// EDITED CODE
context.setBlendMode(.color)
UIColor.subPink.setFill()
context.fill(areaRect)
// EDITED CODE
imageTuple.image.draw(in: areaRect, blendMode: .normal, alpha: 1)
context.restoreGState()
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Учитывается поворот внутри преобразования. Масштабирование внутри преобразования принимается во внимание.
Но перевод внутри преобразования, кажется, не работает (есть крошечный перевод, но он не отражает реального).
Мне явно что-то не хватает, но не могу понять, что.
Любая идея?
EDIT:
Вот несколько скриншотов о том, как выглядит наклейка в приложении, и каково окончательное изображение, сохраненное в библиотеке. Как вы можете видеть, вращение и масштаб (соотношение ширина/высота) конечного изображения такие же, как и в приложении.
UIImageView
, содержащее UIImage
, имеет такое же отношение, что и его изображение.
Я также добавил фон при рисовании наклейки, чтобы четко видеть границы фактического изображения.
Нет вращения или масштабирования:
Поворот и масштабирование:
ИЗМЕНИТЬ 2:
Здесь - тестовый проект, который воспроизводит описанное выше поведение.