我已经有一段时间遇到这个问题了,在这里看了几十个答案,似乎找不到任何有用的东西。
我正在我的应用程序的 iOS 端生成一个二维码,并希望将此二维码发送到我目前正在开发的 WatchKit 扩展。
func createQR(with string: String) {
if let filter = CIFilter(name: "CIQRCodeGenerator") {
//set the data to the contact data
filter.setValue(string, forKey: "inputMessage")
filter.setValue("L", forKey: "inputCorrectionLevel")
if let codeImage = filter.outputImage {
return UIImage(ciImage: codeImage);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想从 QR 图像中获取数据,以便将其发送到 Apple Watch 应用程序,如下所示:
let data = UIImagePNGRepresentation(QRCodeImage);
Run Code Online (Sandbox Code Playgroud)
但是,这总是会返回,nil因为没有图像数据支持过滤器的输出。
注意:我知道没有与 CI Image 关联的数据,因为它没有被渲染,甚至没有与之关联的数据,因为它只是过滤器的输出。我不知道如何解决这个问题,因为我对图像处理等很陌生。:/
cgImage从filter.outputImagefunc createQR(with string: String) {
if let filter = CIFilter(name: "CIQRCodeGenerator") {
//set the data to the contact data
filter.setValue(contactData, forKey: "inputMessage")
filter.setValue("L", forKey: "inputCorrectionLevel")
if let codeImage = filter.outputImage {
let context = CIContext(options: nil)
if let cgImage = context.createCGImage(codeImage, from: codeImage.extent) {
self.QRCode = UIImage(cgImage: cgImage)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这不起作用,它似乎不起作用,因为视图上的图像是空白的。
func update(with string: String) {
let blankCiImage = CIImage(color: .white) //This probably isn't right...
if let filter = CIFilter(name: "CIQRCodeGenerator") {
filter.setValue(contactData, forKey: "inputMessage")
filter.setValue("L", forKey: "inputCorrectionLevel")
filter.setValue(blankCiImage, forKey: kCIInputImageKey)
if let codeImage = filter.outputImage {
let context = CIContext(options: nil)
if let cgImage = context.createCGImage(codeImage, from: codeImage.extent) {
self.contactCode = UIImage(cgImage: cgImage)
print(self.contactCode!)
print(UIImagePNGRepresentation(self.contactCode!))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这也不起作用 - 我的想法是向其中添加一个空白图像,然后在其上执行过滤器,但我可能做得不对。
从字面上看,只是为了从生成的 QR Code 中获取数据。大多数线程都建议UIImage(ciImage: output),但这没有任何支持数据。
如果有人能帮我解决这个问题,那就太好了。任何关于它如何工作的解释也会很棒。
编辑:我不相信这与标记的副本相同 - 标记的副本是关于使用 CI 过滤器编辑现有图像并获取该数据,这是关于仅通过 CI 过滤器创建的图像,没有输入图像 -二维码。另一个答案并不完全相关。
您的代码中有几个问题。在将字符串传递给过滤器之前,您需要使用字符串编码 isoLatin1 将字符串转换为数据。另一个问题是,要将 CIImage 转换为数据,您需要重绘/渲染 CIImage 并防止缩放时图像模糊,您需要对图像应用变换以增加其大小:
extension StringProtocol {
var qrCode: UIImage? {
guard
let data = data(using: .isoLatin1),
let outputImage = CIFilter(name: "CIQRCodeGenerator",
parameters: ["inputMessage": data, "inputCorrectionLevel": "M"])?.outputImage
else { return nil }
let size = outputImage.extent.integral
let output = CGSize(width: 250, height: 250)
let format = UIGraphicsImageRendererFormat()
format.scale = UIScreen.main.scale
return UIGraphicsImageRenderer(size: output, format: format).image { _ in outputImage
.transformed(by: .init(scaleX: output.width/size.width, y: output.height/size.height))
.image
.draw(in: .init(origin: .zero, size: output))
}
}
}
extension CIImage {
var image: UIImage { .init(ciImage: self) }
}
Run Code Online (Sandbox Code Playgroud)
游乐场测试:
let link = "/sf/ask/3582500141/?noredirect=1"
let image = link.qrCode!
let data = image.jpegData(compressionQuality: 1) // 154785 bytes
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1378 次 |
| 最近记录: |