为什么将 SF 符号放入 UIImage 然后放入 SwiftUI Image View 会导致图像模糊?

问题描述

我正在尝试编写一个带有 UIImage 的公共初始化程序,但我想同时允许从照片(或以其他方式绘制)或使用 SF 符号制作的普通的、实际的 UIImage,但我很难过为什么SF符号模糊。我错过了什么?

这是我得到的代码

struct TempuIImageView: View {

    var defaultimage: UIImage = UIImage(systemName: "globe")!

    var defaultimageString: String = "globe"

    var body: some View {
        vstack  {
            Image(uiImage: defaultimage)
                .resizable()
                .scaledToFill()
                .aspectRatio(contentMode: .fit)
            Image(systemName: defaultimageString)
                .resizable()
                .scaledToFill()
                .aspectRatio(contentMode: .fit)
        }
        .padding()
    }
}

我希望在这方面使用解决方案:

@State private var displayedImage: UIImage?

...

private var displayImage: some View {
    Image(uiImage: displayedImage!)
        .resizable()
        .frame(maxWidth: .infinity,maxHeight: .infinity,alignment: .center)
        .scaledToFill()
        .aspectRatio(contentMode: .fit)
        .clipShape(Circle())
        .shadow(radius: 4)
}

但是displayedImage 可以是UIImage 或SF 符号。

(强制解包在其他代码中处理,但无论如何这是初步代码

解决方法

当您使用 Image(systemName:) 时,系统会使用矢量图形绘制到屏幕上,从而产生清晰、不模糊的渲染效果。

然而,UIImage,包括,看起来 UIImage(systemName:) 是一个位图图像,在一个设定的分辨率。如果您将其放大(就像您在第二个代码块中所做的那样),则会变得模糊,因为您没有获得矢量图形的好处。

使用类似以下的模式将允许您有条件地显示 Image(uiImage:)Image(systemName:),并且仍然为每个使用相同的修饰符集:

struct ContentView: View {
    @State var displayedImage : UIImage?
    
    var imageToDisplay: Image {
        if let displayedImage = displayedImage {
            return Image(uiImage: displayedImage)
        } else {
            return Image(systemName: "camera.circle")
        }
    }
    
    var body: some View {
        imageToDisplay
            .resizable()
            .scaledToFill()
            .aspectRatio(contentMode: .fit)
            .frame(width: 400,height: 400)
    }
}