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

问题描述 投票:0回答:2

我正在尝试编写一个需要 UIImage 的公共初始化,但我想允许由照片(或以其他方式绘制)制作的正常的实际 UIImage 或使用 SF 符号,但我很困惑为什么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 Symbol。

(强制解包在其他代码中处理,但这只是初步代码)

swiftui uiimage
2个回答
9
投票

当您使用

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)
    }
}

0
投票

FWIW,如果您有必须使用

UIImage
的限制,您可以通过使用 .applyingSymbolConfiguration
 并设置字体大小和渲染比例来放大 SF 符号 

在你的例子中:

var defaultImage: UIImage = UIImage(systemName: "globe")!
    .applyingSymbolConfiguration(.init(
        font: .systemFont(ofSize: 64),
        scale: .large
    ))

这将以适当的大小和比例渲染

UIImage
位图,因此它应该看起来不模糊。 (但这仍然会导致调整大小时出现问题。)

© www.soinside.com 2019 - 2024. All rights reserved.