如何将 SwiftUI 图像保存到磁盘或取出数据?
How can I save a SwiftUI image to disk or get the data out?
我正在尝试将 SwiftUI 图像(不是来自 UIKit 的 UIImage)保存到磁盘。
我找遍了所有地方,但找不到有关如何执行此操作的任何文档化信息。我也看不到从 SwiftUI 图像中提取数据的方法。
有人可以帮忙吗?提前致谢。
使用 SwiftUI,事情会有所不同。你想做的事,不能以那种方式完成。相反,您需要查看图像是如何创建的,并从您 Image()
最初获取它的相同位置获取图像数据。
此外,如果您需要将实际的二进制数据保存到磁盘,则需要 UIImage
(注意我不是说 UIImageView
)。
幸运的是,Image 也可以处理 UIImage
,请查看另一个问题:
我将 SwiftUI 图像转换为 UIImage,然后将其保存到 UserDefaults。
这不是最好的解决方案,但我没有找到更好的解决方案:
// reading the saved image from userDefaults
private func getSavedImage(for size: String) -> Image? {
if let data = UserDefaults.standard.data(forKey: size) {
if let image = UIImage(data: data) {
return Image(uiImage: image)
}
}
return nil
}
// Converting SwiftUI Image to UIImage
extension View {
public func toUIImage() -> UIImage {
let controller = UIHostingController(rootView: self)
controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
#if targetEnvironment(macCatalyst)
UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
#else
var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return nil
}
return window
}
if let window = window, let rootViewController = window.rootViewController {
var topController = rootViewController
while let newTopController = topController.presentedViewController {
topController = newTopController
}
topController.view.insertSubview(controller.view, at: controller.view.subviews.count)
} else {
print("cant access window")
}
#endif
let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
controller.view.bounds = CGRect(origin: .zero, size: size)
controller.view.sizeToFit()
// here is the call to the function that converts UIView to UIImage: `.asImage()`
let image = controller.view.toUIImage()
controller.view.removeFromSuperview()
return image
}
}
使用顶级助手并保存图像:
extension Image {
func toData()-> Data {
return self.toUIImage().jpegData(compressionQuality: 1)!
}
func save(for name: String) {
UserDefaults.standard.setValue(self.toData(), forKey: name)
}
}
我正在尝试将 SwiftUI 图像(不是来自 UIKit 的 UIImage)保存到磁盘。
我找遍了所有地方,但找不到有关如何执行此操作的任何文档化信息。我也看不到从 SwiftUI 图像中提取数据的方法。
有人可以帮忙吗?提前致谢。
使用 SwiftUI,事情会有所不同。你想做的事,不能以那种方式完成。相反,您需要查看图像是如何创建的,并从您 Image()
最初获取它的相同位置获取图像数据。
此外,如果您需要将实际的二进制数据保存到磁盘,则需要 UIImage
(注意我不是说 UIImageView
)。
幸运的是,Image 也可以处理 UIImage
,请查看另一个问题:
我将 SwiftUI 图像转换为 UIImage,然后将其保存到 UserDefaults。
这不是最好的解决方案,但我没有找到更好的解决方案:
// reading the saved image from userDefaults
private func getSavedImage(for size: String) -> Image? {
if let data = UserDefaults.standard.data(forKey: size) {
if let image = UIImage(data: data) {
return Image(uiImage: image)
}
}
return nil
}
// Converting SwiftUI Image to UIImage
extension View {
public func toUIImage() -> UIImage {
let controller = UIHostingController(rootView: self)
controller.view.frame = CGRect(x: 0, y: CGFloat(Int.max), width: 1, height: 1)
#if targetEnvironment(macCatalyst)
UIApplication.shared.windows.first!.rootViewController?.view.addSubview(controller.view)
#else
var window: UIWindow? {
guard let scene = UIApplication.shared.connectedScenes.first,
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate,
let window = windowSceneDelegate.window else {
return nil
}
return window
}
if let window = window, let rootViewController = window.rootViewController {
var topController = rootViewController
while let newTopController = topController.presentedViewController {
topController = newTopController
}
topController.view.insertSubview(controller.view, at: controller.view.subviews.count)
} else {
print("cant access window")
}
#endif
let size = controller.sizeThatFits(in: UIScreen.main.bounds.size)
controller.view.bounds = CGRect(origin: .zero, size: size)
controller.view.sizeToFit()
// here is the call to the function that converts UIView to UIImage: `.asImage()`
let image = controller.view.toUIImage()
controller.view.removeFromSuperview()
return image
}
}
使用顶级助手并保存图像:
extension Image {
func toData()-> Data {
return self.toUIImage().jpegData(compressionQuality: 1)!
}
func save(for name: String) {
UserDefaults.standard.setValue(self.toData(), forKey: name)
}
}