SwiftUI从String(Base64)解码图像

3

我有一个字符串中的图像(base 64编码),我如何使用SwiftUI对此字符串进行解码以用于Image()。

现在我正在使用这种格式:

Image(imageFromAppGroup(key: "image0")).resizable().frame(width: 70, height: 70)
                            .cornerRadius(10)
                            .background(Color(red: 0.218, green: 0.215, blue: 0.25))

我需要使用过去的base64图片替代"image0"。我该怎么做?
2个回答

8
你可以使用 UIImage 来实现这一点:
let str = "IMAGE"
Image(uiImage: UIImage(data: Data(base64Encoded: str)!)!)

您不应该在此处使用 ! 进行强制解包,因此您也应该处理这个问题:

let str = "IMAGE"

if let data = Data(base64Encoded: str), let uiImage = UIImage(data: data) {
    Image(uiImage: uiImage)
} else {
    let _ = print("FAIL")
}

您也可以创建一个Image扩展:

extension Image {
    init?(base64String: String) {
        guard let data = Data(base64Encoded: base64String) else { return nil }
        guard let uiImage = UIImage(data: data) else { return nil }
        self = Image(uiImage: uiImage)
    }
}

/* ... */

var body: some View {
    Image(base64String: str)
}

根据stackoverflow.com/a/60732521/2926577的说法,在SwiftUI中应避免使用UIImage,因为“这就像在Swift中使用Objective C代码一样,发布新语言没有意义”。这准确吗?如果是,有没有一种方法可以将base64解码为Image()可接受的内容,而不需要使用UIImage? - user2926577
@user2926577 不,如果使用正确的话,使用 UIImage 一点也不糟糕。在 SwiftUI 中,主要的问题是不要在视图的 init 或 body 中初始化 UIImage,特别是 body。这是因为如果 init 花费了很长时间,视图创建就会变慢。如果在 body 中创建 UIImage,它将在每次视图重新加载时重新创建,这是昂贵的。相反,在 onAppear 中创建图像,将其设置为 @State 变量,然后在 body 中创建 SwiftUI Image - George

3

类似这样:

extension Image {
  init?(base64String: String) {
    guard let data = Data(base64Encoded: base64String) else { return nil }
    #if os(macOS)
    guard let image = NSImage(data: data) else { return nil }
    self.init(nsImage: image)
    #elseif os(iOS)
    guard let image = UIImage(data: data) else { return nil }
    self.init(uiImage: image)
    #else
    return nil
    #endif
  }
}

使用方法:

Image(base64String: base64string)

支持 macOS 的想法不错,但我不会创建一个没有明确标签的 init。base64String 提供了上下文,而且 Image 已经有了 Image(_:) 的 init,所以这可能会引起问题。 - George

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接