mindfreek
mindfreek

Reputation: 704

Saving an image on top of another image in Swift

I am learning Swift and I am creating an app that uses a personal photo and puts another on top of it. I now have a hacky solution, to create a screenshot of the area and save it. I need to do this in Swift

@IBAction func saveImage(sender: AnyObject) {
    //Create the UIImage
    UIGraphicsBeginImageContext(imageView.frame.size)
    view.layer.renderInContext(UIGraphicsGetCurrentContext())
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    //Save it to the camera roll
    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
}

But, this was working and isn't anymore. But, this is also not the best solution.

So guys, how can I save an image to the camera roll from a personal image, with an image as overlay?

Help would be greatly appreciated!! Thanks!

Upvotes: 14

Views: 18366

Answers (4)

Adrian
Adrian

Reputation: 555

Apple advises against UIGraphicsBeginImageContext, so as long as your app does not support devices older than iOS 10, then use something like this:

private func drawLogoIn(_ image: UIImage, _ logo: UIImage, position: CGPoint) -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: image.size)
    return renderer.image { context in
        image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
        logo.draw(in: CGRect(origin: position, size: logo.size))
    }
}

Besides performance gains, you get full P3 range.

Upvotes: 13

Carter Cobb
Carter Cobb

Reputation: 840

UPDATE FOR SWIFT 4

func saveImage() {
    let bottomImage = UIImage(named: "your bottom image name")!
    let topImage = UIImage(named: "your top image name")!            
    let newSize = CGSize(width: 100, height: 100)   // set this to what you need
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
    bottomImage.draw(in: CGRect(origin: CGPoint.zero, size: newSize))
    topImage.draw(in: CGRect(origin: CGPoint.zero, size: newSize))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}

To use the image just refer to newImage

EXAMPLE HOW TO USE THE IMAGE:

@IBOutlet weak var imageButton: UIButton!
imageButton.setBackgroundImage(newImage), for: .normal) 

This is an edit of cnoon's answer but optimized for Swift 4.

Upvotes: 6

quin
quin

Reputation: 474

Updated to Swift 3.0:

func saveImage() {
    let bottomImage = UIImage(named: "bottom")!
    let topImage = UIImage(named: "top")!

    let newSize = CGSizeMake(100, 100) // set this to what you need
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)

    bottomImage.draw(in: CGRect(origin: CGPointZero, size: newSize))//As drawInRect is deprecated
    topImage.draw(at: CGRect(origin: CGPointZero, size: newSize))//As drawInRect is deprecated

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}

Upvotes: 3

cnoon
cnoon

Reputation: 16663

I would recommend reading through this thread. All your answers are there. Once you read through that article, the following code sample should help you composite the two images together properly.

func saveImage() {
    let bottomImage = UIImage(named: "bottom")!
    let topImage = UIImage(named: "top")!

    let newSize = CGSizeMake(100, 100) // set this to what you need
    UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)

    bottomImage.drawInRect(CGRect(origin: CGPointZero, size: newSize))
    topImage.drawInRect(CGRect(origin: CGPointZero, size: newSize))

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
}

Hopefully this gets you going in the right direction.

Upvotes: 38

Related Questions