#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, поэтому кодировка никогда не беспокоила меня.