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