Using that method, you get an image of what is rendered on the screen.
What you want to do is calculate the "sticker" size and placement relative to the scaled image and then combine the images.
You can use this extension to overlay one image on another:
extension UIImage {
func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
let rFormat = UIGraphicsImageRendererFormat()
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
let newImage = renderer.image {
(context) in
self.draw(at: .zero)
image.draw(at: CGPoint(x: posX, y: posY))
}
return newImage
}
}
Use it by calling (for example):
let combinedImage = bkgImage.overlayWith(image: stickerImage, posX: 1000.0, posY: 1000.0)
That says "Create a new UIImage
by overlaying the sticker image onto the background image at x: 1000, y:1000
"
Remember that you'll need to translate your coordinates... So, if you are showing your 7680 x 4320
image in a 200 x 400
scrollview (not taking any zooming into account here), the on-screen image size will be 711 x 400
. If the user places the sticker at 100, 50
, the actual position on the original size image will be:
let scaleFactor = bkgImage.size.height / 400.0
let x = 100.0 * scaleFactor
let y = 50.0 * scaleFactor
// scaleFactor equals 10.8
// x equals 100 * 10.8 == 1080
// y equals 50 * 10.8 == 540
let combinedImage = bkgImage.overlayWith(image: stickerImage, posX: x, posY: y)
Here is a basic sample you can try out.
It starts with a background image of 5120 x 2880
:

and a "sticker" image at 512 x 512
:

And the result, with the sticker placed at x: 1000, y:1000
. Top image is original background (aspectFit), middle image is the combined image (again, aspectFit), and the bottom image is the actual size combined image in a scroll view:

Use this source code to run that example (all code, no @IBoutlet
):
import UIKit
extension UIImage {
func overlayWith(image: UIImage, posX: CGFloat, posY: CGFloat) -> UIImage {
let rFormat = UIGraphicsImageRendererFormat()
let renderer = UIGraphicsImageRenderer(size: size, format: rFormat)
let newImage = renderer.image {
(context) in
self.draw(at: .zero)
image.draw(at: CGPoint(x: posX, y: posY))
}
return newImage
}
}
class ViewController: UIViewController {
let origImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFit
v.backgroundColor = .yellow
return v
}()
let modImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .scaleAspectFit
v.backgroundColor = .yellow
return v
}()
let actualSizeImageView: UIImageView = {
let v = UIImageView()
v.translatesAutoresizingMaskIntoConstraints = false
v.contentMode = .topLeft
v.backgroundColor = .yellow
return v
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
guard let bkgImage = UIImage(named: "background"),
let stickerImage = UIImage(named: "sticker") else {
fatalError("missing images")
}
view.backgroundColor = .systemGreen
view.addSubview(origImageView)
view.addSubview(modImageView)
view.addSubview(scrollView)
scrollView.addSubview(actualSizeImageView)
let g = view.safeAreaLayoutGuide
let sg = scrollView.contentLayoutGuide
NSLayoutConstraint.activate([
origImageView.topAnchor.constraint(equalTo: g.topAnchor, constant: 10.0),
origImageView.centerXAnchor.constraint(equalTo: g.centerXAnchor, constant: 0.0),
origImageView.widthAnchor.constraint(equalToConstant: 200.0),
origImageView.heightAnchor.constraint(equalToConstant: 120.0),
modImageView.topAnchor.constraint(equalTo: origImageView.bottomAnchor, constant: 10.0),
modImageView.centerXAnchor.constraint(equalTo: origImageView.centerXAnchor, constant: 0.0),
modImageView.widthAnchor.constraint(equalTo: origImageView.widthAnchor),
modImageView.heightAnchor.constraint(equalTo: origImageView.heightAnchor),
scrollView.topAnchor.constraint(equalTo: modImageView.bottomAnchor, constant: 10.0),
scrollView.centerXAnchor.constraint(equalTo: origImageView.centerXAnchor, constant: 0.0),
scrollView.widthAnchor.constraint(equalTo: g.widthAnchor, constant: -10.0),
scrollView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -10.0),
actualSizeImageView.topAnchor.constraint(equalTo: sg.topAnchor),
actualSizeImageView.bottomAnchor.constraint(equalTo: sg.bottomAnchor),
actualSizeImageView.leadingAnchor.constraint(equalTo: sg.leadingAnchor),
actualSizeImageView.trailingAnchor.constraint(equalTo: sg.trailingAnchor),
actualSizeImageView.widthAnchor.constraint(equalToConstant: bkgImage.size.width),
actualSizeImageView.heightAnchor.constraint(equalToConstant: bkgImage.size.height),
])
origImageView.image = bkgImage
let combinedImage = bkgImage.overlayWith(image: stickerImage, posX: 1000.0, posY: 1000.0)
modImageView.image = combinedImage
actualSizeImageView.image = combinedImage
}
}