I have an array of images and need to merge these images with different blending options. I found, that during this process memory is not released each step of cycle. Even if there are no references to images which were created. My app crashes during this process because I have many images to merge. Is there any workaround or trick how I can do it without memory increasing? It is possible to reproduce with the following code:
import UIKit
import CoreImage
class ViewController: UIViewController {
var images =
[
UIImage.init(color: UIColor.green, size: CGSize(width: 2048, height: 1152))!,
UIImage.init(color: UIColor.green, size: CGSize(width: 2048, height: 1152))!,
UIImage.init(color: UIColor.green, size: CGSize(width: 2048, height: 1152))!,
UIImage.init(color: UIColor.green, size: CGSize(width: 2048, height: 1152))!,
UIImage.init(color: UIColor.green, size: CGSize(width: 2048, height: 1152))!,
]
override func viewDidLoad() {
super.viewDidLoad()
var result = UIImage.init(color: UIColor.blue, size: CGSize(width: 2048, height: 1152))!
for image in images {
//each step reference to previous result released, but memory is growing
result = merge(result, image)
sleep(1)
}
}
public func merge(_ back: UIImage, _ top: UIImage) -> UIImage {
var size = CGSize(width: 2048, height: 1152)
UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
let rec = CGRect(x: 0, y: 0, width: 2048, height: 1152)
back.draw(in: rec)
//multiply is just for example, it can be different blending option
top.draw(in: rec, blendMode: .multiply, alpha: 1)
var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return newImage
}
}
extension UIImage {
public convenience init?(color: UIColor, size: CGSize) {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(rect.size, true, 0)
color.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard let cgImage = image?.cgImage else {
return nil
}
self.init(cgImage: cgImage, scale: UIScreen.main.scale, orientation: Orientation.up)
}
}
Array with dummy images and cycle. I added sleep to see it better in Instruments
(without sleep it has the same result)
As you can see each second memory is increasing. Any way to keep memory on same level each step? Many thanks!