【发布时间】:2021-03-17 15:50:03
【问题描述】:
我可以使用下面的代码将任何 SwiftUI 视图转换为高分辨率的 UIImage。效果很好...直到...我尝试使用大于 CGSize(width: 2730, height: 2730) 的图像尺寸。
如果我将图像尺寸增加到 CGSize(width: 2731, height: 2731) 或更大,则行:
self.drawHierarchy(in: self.layer.bounds, afterScreenUpdates: true)
在“扩展UIView”中,无法再绘制UIImage。
知道为什么会有尺寸限制吗?
注意:我可以通过取消注释“扩展视图”中的 2 行并替换来克服大小限制:
self.drawHierarchy(in: self.layer.bounds, afterScreenUpdates: true)
与:
layer.render(in: context.cgContext)
在“扩展 UIView”... 但是 THEN “layer.render” 不会渲染图像效果,例如“模糊”、SceneKit 子视图或金属。所以使用“self.drawHierarchy”是必须的。
// 1: Set breakpoint on line: print("done") to inspect the high res image
// 2: Run, then tap the image on screen to inspect the highresImage
// 3: repeat after changing the size to CGSize = CGSize(width: 2731, height: 2731)
import SwiftUI
struct ContentView: View {
@State var blurRadius: CGFloat = 4.0
let imageSize: CGSize = CGSize(width: 2730, height: 2730)
var body: some View {
testView
.frame(width: 300, height: 300)
.onTapGesture {
// Adjust blur radius based on high res image scale
blurRadius *= imageSize.width * 0.5/300
// Capture high res image of swiftUI view
let highresImage = testView.asImage(size: imageSize)
// set breakpoint here to inspect the high res image size, quality, etc.
print("done")
// reset blur radius back to 4
blurRadius = 4
}
}
var testView: some View {
ZStack {
Color.blue
Circle()
.fill(Color.red)
}
.blur(radius: blurRadius)
}
}
extension UIView {
func asImage() -> UIImage {
let format = UIGraphicsImageRendererFormat()
format.scale = 1
return UIGraphicsImageRenderer(size: self.layer.frame.size, format: format).image { context in
self.drawHierarchy(in: self.layer.bounds, afterScreenUpdates: true)
//layer.render(in: context.cgContext)
}
}
}
extension View {
func asImage(size: CGSize) -> UIImage {
let controller = UIHostingController(rootView: self)
controller.view.bounds = CGRect(origin: .zero, size: size)
//UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
let image = controller.view.asImage()
//controller.view.removeFromSuperview()
return image
}
}
【问题讨论】:
-
在 iPad Pro(似乎是 2x)上,限制为 4096。同样,如果您使用
8192.0 / UIScreen.main.nativeScaleApple 可能硬编码了 8192x8192 像素限制,您仍然可以在 3x iPhone 上渲染 8192x8192 图像用于渲染视图。
标签: view swiftui uiimage uigraphicsimagerenderer