使用 SwiftUI 生成二维码显示空图片

Generating QR Code with SwiftUI shows empty picture

我正在尝试在我的应用程序中生成二维码。问题是每当我这样做时,图片只是一个空方块。我将代码精简到最基本的部分,以尝试展示我的问题。

struct ContentView: View {
    @State var image: Image = Image(systemName: "circle.fill")

    var body: some View {
        VStack {
            image
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 200, height: 200)
                .background(Color.green)

        }.onAppear {
            let myString = "Hello There"
            let data = myString.data(using: String.Encoding.ascii)
            guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return }
            qrFilter.setValue(data, forKey: "inputMessage")
            guard let qrImage = qrFilter.outputImage else { return }
            let transform = CGAffineTransform(scaleX: 10, y: 10)
            let scaledQrImage = qrImage.transformed(by: transform)
            self.image = Image(uiImage: UIImage(ciImage: scaledQrImage))
        }
    }
}

结果是这样的:

我想问题是你的 CIImage 实际上不是 "produced"。你看,CIImage 只是一个 recipe 需要由 CIContext 渲染成实际位图图像的图像。

(记录不详的)方便的初始化程序 UIImage(ciImage:) 仅当您将图像分配到的目的地理解 UIImage 的像素尚未 时才有效 并且需要先渲染。 UIImageView 可以解决这个问题,但 SwiftUI 的 Image 似乎不能。

您需要做的是创建一个 CIContext(一次,可能作为您视图的 属性)并使用它来将您的条形码图像渲染成这样的位图:

let cgImage = self.ciContext.createCGImage(scaledQrImage, from: scaledQrImage.extent)
self.image = Image(uiImage: UIImage(cgImage: cgImage))
func returnQRData(str: String) -> Data {
     let filter = CIFilter(name: "CIQRCodeGenerator")
     let data = str.data(using: .ascii, allowLossyConversion: false)
     filter?.setValue(data, forKey: "inputMessage")
     let transform = CGAffineTransform(scaleX: 5, y: 5)


     let image = filter?.outputImage?.transformed(by: transform)
     let uiImage = UIImage(ciImage: image!)

     return uiImage.pngData()!
}

Image(uiImage: UIImage(data: self.returnQRData(str: "www.apple.com")) ?? UIImage(named: "noImage1")!)
    .resizable()
    .aspectRatio(contentMode: .fit)
    .padding()