SwiftUI - 保存图像以共享 Sheet 导致图像保存 blurry/low res

SwiftUI - Saving Image to Share Sheet causes image to save blurry/low res

我的应用程序中有一些代码可以生成二维码并将其放大(我使用的代码参考来自 this link from Hackng with Swift。现在,我正在使用共享 sheet 允许用户将二维码保存到他们的相机胶卷,它正在工作,但保存图像分辨率低,并且它保存到相机胶卷模糊(我假设如果它通过其他方法共享它也会模糊)

这是我的分享sheet功能的代码:

struct ActivityView: UIViewControllerRepresentable {

    let activityItems: [Any]
    let applicationActivities: [UIActivity]?

    func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
        return UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {

    }
}

这是我的视图结构中的代码:

.sheet(isPresented: $showShareSheet) {
                    ShareSheet(activityItems: [self.qrCodeImage])
                }

当图像视图本身上的 .interpolation(.none) 保存到共享 sheet 时,是否有删除图像插值的技巧?

你的问题是二维码图片太小了!像真的很小:

Printing description of image:
<UIImage:0x60000202cc60 anonymous {23, 23}>

当您分享此图片时,它的显示方式取决于将显示它的程序或应用程序,据我所知不受您的应用程序控制。


然而,

有一种方法可以使它在其他应用程序中变得“漂亮”,这就是将分辨率提高到更大的数量,以便在渲染时看起来具有“锐利”的像素。

这将如何实现?我想我有一个隐藏在旧代码某处的示例,我会深入研究它,看看是否能为您找到一个示例;)

编辑

我找到了代码:

extension UIImage {
    func resized(toWidth width: CGFloat) -> UIImage? {
        let canvasSize = CGSize(width: round(width), height: CGFloat(ceil(width/size.width * size.height)))
        UIGraphicsBeginImageContextWithOptions(canvasSize, false, scale)
        defer { UIGraphicsEndImageContext() }
        let context = UIGraphicsGetCurrentContext();
        context?.interpolationQuality = .none
        // Set the quality level to use when rescaling
        draw(in: CGRect(origin: .zero, size: canvasSize))
        let r = UIGraphicsGetImageFromCurrentImageContext()
        return r
    }
}

诀窍是提供一种缩放图像的方法,但真正的魔法在第 7 行:

context?.interpolationQuality = .none

如果您排除这条线,您将得到模糊的图像,这是 OS 默认情况下所做的,因为您通常不希望看到图像中的像素边缘。

您可以像这样使用此扩展程序:

.sheet(isPresented: $showShareSheet) {
    ShareSheet(activityItems: [self.qrCodeImage.resized(toWidth: 512) ?? UIImage()])
}

但是,这可能会导致不必要地更频繁地调整图像大小。最佳情况下,您会在生成它的同一函数中调整它的大小。