Swift: how can I add an image to another image?

Viewed 4075

Will you please direct me to right path of how to select another transparent picture and add it over to another picture?
Transparent pictures like: a clown nose, hat, cap, earrings, mustache, glasses etc.
Its exist in several applications but i cant find any Swift sample about this.

Thanks for your help.

1 Answers

I have a nice function on an UIImage extension:

extension UIImage {

    static func imageByMergingImages(topImage: UIImage, bottomImage: UIImage, scaleForTop: CGFloat = 1.0) -> UIImage {
        let size = bottomImage.size
        let container = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
        UIGraphicsGetCurrentContext()!.interpolationQuality = .high
        bottomImage.draw(in: container)

        let topWidth = size.width / scaleForTop
        let topHeight = size.height / scaleForTop
        let topX = (size.width / 2.0) - (topWidth / 2.0)
        let topY = (size.height / 2.0) - (topHeight / 2.0)

        topImage.draw(in: CGRect(x: topX, y: topY, width: topWidth, height: topHeight), blendMode: .normal, alpha: 1.0)

        return UIGraphicsGetImageFromCurrentImageContext()!
    }

}

So you can call in this way:

let image = UIImage.imageByMergingImages(topImage: top, bottomImage: bottom)

For your specific case, considering that you want to add many overlays over an image, you should have a function like this:

extension UIImage {

    func imageOverlayingImages(_ images: [UIImage], scalingBy factors: [CGFloat]? = nil) -> UIImage {
        let size = self.size
        let container = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(size, false, 2.0)
        UIGraphicsGetCurrentContext()!.interpolationQuality = .high

        self.draw(in: container)

        let scaleFactors = factors ?? [CGFloat](repeating: 1.0, count: images.count)

        for (image, scaleFactor) in zip(images, scaleFactors) {
            let topWidth = size.width / scaleFactor
            let topHeight = size.height / scaleFactor
            let topX = (size.width / 2.0) - (topWidth / 2.0)
            let topY = (size.height / 2.0) - (topHeight / 2.0)

            image.draw(in: CGRect(x: topX, y: topY, width: topWidth, height: topHeight), blendMode: .normal, alpha: 1.0)
        }
        return UIGraphicsGetImageFromCurrentImageContext()!
    }

}

Then you can compose your final image in this way:

var imageClownFace = UIImage(named: "clown_face")!
imageClownFace = imageClownFace.imageOverlayingImages([imageNose, imageHat, imageCap])
Related