从Uiview获取快照的最佳方法
我正在通过拍摄快照(每秒30次)制作视频,我真的需要找到最好的方法,以最佳的性能在后台线程中获得快照。
我有两种方法在Uiview扩展程序中,
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)
}
}
}
第一个snapshotinmain
在主线程中完全执行,它冻结了应用程序,但是屏幕截图本身更快地拍摄了,我从中获得了一个更平稳的视频
snapshotinbackground
,该图层和边界是在主线程中计算的,但随后将在后台执行,但比在MAIN中执行的层较慢(首先 一)。 它的工作就像
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)
}
}
我的工作确实对此非常不满意,我很呆在这里,真的需要帮助。请帮助我找到最好的选择。我的主要要求是 1-应用不应冻结 2-拍摄快照应该很快,我可以每秒钟30次。
谢谢你!期待您的帮助
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用计时器在主线程上节拍快照。这是一个示例
,该示例
将
TimeInterval
降低到0.01
在此期间的CPU使用率约为20%左右,并且该应用程序在我的琐碎示例中根本没有落后。
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.
而不是采用快照我使用发电机是一个不错的选择,而是需要CPU,而不是导致UI/UX更平滑的内存
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