Как я могу добавить квадратное изображение в QR-код | Swift

#swift #qr-code

Вопрос:

По сути, у меня есть следующая функция QR — кода, которая успешно создает QR-код на основе заданной строки-как добавить квадратное изображение в центр этого QR-кода, которое является статичным независимо от того, какую строку представляет код?

 The following is the function I use to generate:
    func generateQRCode(from string: String) -> UIImage? {
        let data = string.data(using: String.Encoding.ascii)
        if let filter = CIFilter(name: "CIQRCodeGenerator") {
            filter.setValue(data, forKey: "inputMessage")
            let transform = CGAffineTransform(scaleX: 3, y: 3)
            if let output = filter.outputImage?.transformed(by: transform) {
                return UIImage(ciImage: output)
            }
        }
        return nil
    }
 

Комментарии:

1. Это всего лишь изображение, так что просто нарисуйте поверх него свое наложенное изображение. Единственная проблема заключается в том, что вам придется добавить filter.setValue("Q", forKey: "inputCorrectionLevel") , чтобы увеличить уровень коррекции QR-кода. Это позволит считывать QR-код, даже если часть его будет отсутствовать в центре.

2. Не могли бы вы показать пример того, как нарисовать наложенное изображение — я ценю вашу помощь

Ответ №1:

Пример кода из одного из моих приложений, только слегка прокомментированный. Расчеты размера, возможно, не потребуются для вашего приложения.

 func generateImage(code: String, size pointSize: CGSize, logo: UIImage? = nil) -> UIImage? {
    let pixelScale = UIScreen.main.scale
    let pixelSize = CGSize(width: pointSize.width * pixelScale, height: pointSize.height * pixelScale)

    guard
        let codeData = code.data(using: .isoLatin1),
        let generator = CIFilter(name: "CIQRCodeGenerator")
    else {
        return nil
    }

    generator.setValue(codeData, forKey: "inputMessage")
    // set higher self-correction level
    generator.setValue("Q", forKey: "inputCorrectionLevel")

    guard let codeImage = generator.outputImage else {
        return nil
    }

    // calculate transform depending on required size
    let transform = CGAffineTransform(
        scaleX: pixelSize.width / codeImage.extent.width,
        y: pixelSize.height / codeImage.extent.height
    )

    let scaledCodeImage = UIImage(ciImage: codeImage.transformed(by: transform), scale: 0, orientation: .up)

    guard let logo = logo else {
        return scaledCodeImage
    }

    // create a drawing buffer
    UIGraphicsBeginImageContextWithOptions(pointSize, false, 0)
    defer {
        UIGraphicsEndImageContext()
    }

    // draw QR code into the buffer
    scaledCodeImage.draw(in: CGRect(origin: .zero, size: pointSize))

    // calculate scale to cover the central 25% of the image
    let logoScaleFactor: CGFloat = 0.25
    // update depending on logo width/height ratio
    let logoScale = min(
        pointSize.width * logoScaleFactor / logo.size.width,
        pointSize.height * logoScaleFactor / logo.size.height
    )

    // size of the logo
    let logoSize = CGSize(width: logoScale * logo.size.width, height: logoScale * logo.size.height)

    // draw the logo
    logo.draw(in: CGRect(
        x: (pointSize.width - logoSize.width) / 2,
        y: (pointSize.height - logoSize.height) / 2,
        width: logoSize.width,
        height: logoSize.height
    ))

    return UIGraphicsGetImageFromCurrentImageContext()!
}
 

Комментарии:

1. Зачем принудительно разворачивать результат, если вы уже возвращаете необязательный?

2.Кстати, кодировка строки должна быть isoLatin1 «Чтобы создать QR-код из строки или URL-адреса, преобразуйте его в объект NSData с помощью кодировки строки NSISOLatin1StringEncoding».

3. @LeoDabus Я исправил кодировку. Я использую QR-коды только в контекстах ASCII, поэтому кодировка никогда не беспокоила меня.