【问题标题】:Generating QR Code with SwiftUI shows empty picture用 SwiftUI 生成二维码显示空白图片
【发布时间】:2020-02-03 00:05:06
【问题描述】:

我正在尝试在我的应用中生成二维码。问题是每当我这样做时,图片只是一个空的正方形。我将代码简化为基础,试图展示我的问题。

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

结果是这样的:

【问题讨论】:

标签: qr-code swiftui cifilter


【解决方案1】:

我想问题在于您的CIImage 实际上并没有“生产”。你看,CIImage 只是一个图像的配方,需要由CIContext 渲染成实际的位图图像。

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

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

let cgImage = self.ciContext.createCGImage(scaledQrImage, from: scaledQrImage.extent)
self.image = Image(uiImage: UIImage(cgImage: cgImage))

【讨论】:

  • 您正在为我们所有人开辟道路!很好的答案。
【解决方案2】:
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()

【讨论】:

  • 这非常低效,因为returnQRData 不必要地将图像编码为 PNG 数据流,只是为了立即再次解码。使用 CIContext 渲染到 CGImage 将实现相同的事情,而无需编码为 PNG
猜你喜欢
  • 2015-02-06
  • 1970-01-01
  • 2016-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多