I’m making video from taking snapshots (30 times per sec), and I really need to find the best approach to get snapshot in the background thread with the best possible performance.
I have two approach in UIView extension
extension UIView {
func snapshotInMain(view: UIView) -> UIImage {
let render = UIGraphicsImageRenderer(size: view.bounds.size)
let image = render.image { (context) in
view.drawHierarchy(in: view.bounds, afterScreenUpdates: true)
}
return image
}
func snapShotInBackground(viewLayer: CALayer, viewBounds: CGRect) -> UIImage {
let renderer = UIGraphicsImageRenderer(bounds: viewBounds)
return renderer.image { rendererContext in
viewLayer.render(in: rendererContext.cgContext)
}
}
}
The first one snapshotInMain
completely execute in main thread, it froze the app but the screenshot itself is taken faster and I have a smoother video from it
the second one snapShotInBackground
, the layer and bounds are calculated in the main thread, but then will execute in background, but it’s way slower from the the one that execute in main (first one).
it works like that
DispatchQueue.main.async {
let layer = self.selectedView.layer
let bounds = self.selectedView.bounds
DispatchQueue.global(qos: .background).async {
let image = self.selectedView.snapShotInBackground(viewLayer: layer, viewBounds: bounds)
}
}
My job is really depand on it, I’m pretty stuck here and really need help. please help me to find the best option possible. My main requests are
1- App should not freeze
2- The taking snapshot should be fast that I can do it 30 times per sec.
Thank you! Looking forward to your help
2
Answers
You can use a Timer to throttle the snapshots on the main thread. Here’s an example
which results in
Decreasing the
timeInterval
to0.01
yieldsCPU usage peaked around 20% during this time and the app did not lag at all in my trivial example.
Rather than taking the snapshot I thing use generator is a good option here it takes cpu but not memory which cause smoother ui/ux