Swift-来自CIImage QR代码的图像数据/如何呈现CIFilter输出 [英] Swift - Image Data From CIImage QR Code / How to render CIFilter Output

查看:102
本文介绍了Swift-来自CIImage QR代码的图像数据/如何呈现CIFilter输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到这个问题已有一段时间了,在这里看了几十个答案,似乎找不到任何有用的东西。

I've been having this problem for a while now and looked at dozens of answers here and can't seem to find anything that helps.

我正在应用的iOS端生成QR码,并希望将此QR码发送到我当前正在开发的WatchKit扩展程序中。

I am generating a QR Code on the iOS side of my app and want this QR code to be sent to the WatchKit Extension that I am currently developing.

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



我接下来要做什么



我想从QR图像中获取数据,以便可以将其发送到Apple Watch应用,例如:

What I want next

I want to get the data from the QR image so that I can send it to the Apple Watch app, like so:

let data = UIImagePNGRepresentation(QRCodeImage);

但是,这总是返回 nil ,因为没有图像数据支持过滤器的输出。

But, This always returns nil because there is no image data backing the output from the filter.


注意:知道没有与CI映像关联的数据,因为它尚未渲染,甚至没有与之关联的数据,因为它只是过滤器的输出。 我不知道该如何解决,因为我在图像处理等方面还很陌生。 :/

Note: I know that there is no data associated with the CI Image because it hasn't been rendered and doesn't even have data associated with it because it's just the output from the filter. I don't know how to get around this because I'm pretty new to image processing and such. :/



我尝试过的东西



创建 cgImage 来自 filter.outputImage



What I've Tried

Creating a cgImage from the filter.outputImage

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




但这似乎行不通,因为视图上的图像是空白的。

But this doesn't work, it doesn't seem, because the image on the view is blank.



将空白CIImage创建为输入图像



Creating a blank CIImage as Input Image

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




这也不起作用-我的想法是向其添加空白图像,然后进行过滤

This doesn't work either - my thought was to add a blank image to it and then do the filter on top of it, but I am probably not doing this right.



我的目标



从字面上看,只是从生成的QR码中获取数据。大多数线程建议 UIImage(ciImage:output),但这没有任何后备数据。

My Goal

Literally, just to get the data from the generated QR Code. Most threads suggest UIImage(ciImage: output) , but this doesn't have any backing data.

如果有人可以帮助我解决这个问题,那就太好了。

If anyone could help me out with this, that'd be great. And any explanation on how it works would be wonderful too.

编辑:我不认为这与标记的重复项相同-标记的重复项是关于使用CI过滤器编辑现有图像并获取该数据的信息,这是关于仅通过CI过滤器创建而没有输入图像的图像-QR码。

I don't believe this is the same as the marked duplicate - The marked duplicate is about editing an existing image using CI filters and getting that data and this is about an image that is solely created through CI filter with no input image - QR Codes. the other answer did not fully relate.

推荐答案

您的代码中有几个问题。您需要先使用String Encoding isoLatin1将字符串转换为数据,然后再将其传递给过滤器。另一个问题是要将CIImage转换为数据,您需要重绘/渲染CIImage并防止在缩放时模糊图像,您需要对图像进行转换以增加其大小:

You have a couple of issues in your code. You need to convert your string to data using String Encoding isoLatin1 before passing it to the filter. Another issue is that to convert your CIImage to data you need to redraw/render your CIImage and to prevent blurring the image when scaled you need to apply a transform to the image to increase its size:

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






游乐场测试:


Playground testing:

let link = "https://stackoverflow.com/questions/51178573/swift-image-data-from-ciimage-qr-code-how-to-render-cifilter-output?noredirect=1"
let image = link.qrCode!
let data =  image.jpegData(compressionQuality: 1)  // 154785 bytes

这篇关于Swift-来自CIImage QR代码的图像数据/如何呈现CIFilter输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆