Swift - данные изображения из CIImage QR Code / Как отобразить вывод CIFilter - PullRequest
0 голосов
/ 04 июля 2018

У меня уже давно есть эта проблема, и я посмотрел здесь десятки ответов и, похоже, не могу найти ничего полезного.

Сценарий

Я создаю QR-код на iOS-стороне своего приложения и хочу, чтобы этот QR-код был отправлен на расширение WatchKit, которое я сейчас разрабатываю.

Как я генерирую QR-код

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, например:

let data = UIImagePNGRepresentation(QRCodeImage);

Но, Это всегда возвращает nil, потому что нет данных изображения, поддерживающих выходные данные фильтра.

Примечание: Я знаю, что нет никаких данных, связанных с изображением CI, потому что оно не было визуализировано и даже не имеет данных, связанных с ним, потому что это просто вывод из фильтра. Я не знаю, как обойти это , потому что я довольно плохо знаком с обработкой изображений и тому подобным. : /

Что я пробовал

Создание cgImage из 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)
            }
        }
    }
}

Но это не работает, кажется, потому что изображение на виде пустое.

Создание пустого CIImage в качестве входного изображения

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

Это тоже не работает - я думал добавить пустое изображение к нему, а затем сделать фильтр поверх него, но я, вероятно, не делаю этого правильно.

Моя цель

Буквально, только для получения данных из сгенерированного QR-кода . Большинство потоков предлагают UIImage(ciImage: output), но у этого нет никаких данных поддержки.

Если бы кто-нибудь мог мне помочь с этим, это было бы здорово. И любое объяснение того, как это работает, было бы замечательно.

Редактировать: Я не верю, что это то же самое, что и помеченный дубликат. Помеченный дубликат предназначен для редактирования существующего изображения с использованием фильтров CI и получения этих данных, а для изображения - исключительно созданный через фильтр CI без входного изображения - QR-коды. другой ответ не полностью соответствовал.

1 Ответ

0 голосов
/ 05 июля 2018

У вас есть пара проблем в вашем коде. Вам нужно преобразовать вашу строку в данные, используя String Encoding isoLatin1, прежде чем передавать ее в фильтр. Другая проблема заключается в том, что для преобразования вашего CIImage в данные вам необходимо перерисовать / визуализировать ваш CIImage и, чтобы предотвратить размывание изображения при масштабировании, необходимо применить преобразование к изображению, чтобы увеличить его размер:

extension String {
    var qrCode: UIImage? {
        guard
            let data = data(using: .isoLatin1),
            let filter = CIFilter(name: "CIQRCodeGenerator")
            else { return nil }
        filter.setValue(data, forKey: "inputMessage")
        filter.setValue("M", forKey: "inputCorrectionLevel")
        guard let image = filter.outputImage
            else { return nil }
        let size = image.extent.integral
        let output = CGSize(width: 250, height: 250)
        let matrix = CGAffineTransform(scaleX: output.width / size.width, y: output.height / size.height)
        UIGraphicsBeginImageContextWithOptions(output, false, 0)
        defer { UIGraphicsEndImageContext() }
        UIImage(ciImage: image.transformed(by: matrix))
            .draw(in: CGRect(origin: .zero, size: output))
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

Тестирование игровой площадки:

let link = "/10456649/swift-dannye-izobrazheniya-iz-ciimage-qr-code-kak-otobrazit-vyvod-cifilter"
let image = link.qrCode!
let data =  image.jpegData(compressionQuality: 1)  // 154785 bytes

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...