swift生成一个qrcode

时间:2018-02-23 08:47:43

标签: swift optional

我尝试生成qrcode,但它有错误

  

线程1:致命错误:在解包可选值时意外发现nil

let myString = "ggigiuui"

let data = myString.data(using: .ascii, allowLossyConversion: false)
let filter = CIFilter(name: "CIQRCodeGenerator")
filter?.setValue(data, forKey: "inputMessage")

let img = UIImage(ciImage: (filter?.outputImage)!)

qponImage.image = img

enter image description here

4 个答案:

答案 0 :(得分:2)

请试试这个,

let p = UIBezierPath()
p.move(to: CGPoint(x: 400, y: 200))
p.addLine(to: CGPoint(x: 500, y: 100))
p.addLine(to: CGPoint(x: 400, y: 0))
p.close()

let b = PDFBorder()
b.lineWidth = 10.0

let pageBounds = page.bounds(for: .artBox)
let inkAnnotation = PDFAnnotation(bounds: pageBounds, forType: PDFAnnotationSubtype.ink, withProperties: nil)
inkAnnotation.add(p)
inkAnnotation.border = b
inkAnnotation.color = .green

page.addAnnotation(inkAnnotation)

答案 1 :(得分:1)

我使用了以下代码,它运行正常。其中self.imgQRCode是要在其上显示QR的imageview。

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

            guard let qrImage = filter.outputImage else {return nil}
            let scaleX = self.imgQRCode.frame.size.width / qrImage.extent.size.width
            let scaleY = self.imgQRCode.frame.size.height / qrImage.extent.size.height
            let transform = CGAffineTransform(scaleX: scaleX, y: scaleY)

            if let output = filter.outputImage?.transformed(by: transform)
            {
                return UIImage(ciImage: output)
            }
        }
        return nil
    }

答案 2 :(得分:0)

这是生成QRCode并显示在UIImageView中的方式

首先创建新的可可接触类 .swift 文件并导入以下两个框架:

import UIKit
import CoreImage

,第二步,您只需在同一 .swift 上添加 URL CIImage 扩展名。 >文件。

扩展名:

extension URL {

    /// Creates a QR code for the current URL in the given color.
    func qrImage(using color: UIColor, logo: UIImage? = nil) -> CIImage? {
        let tintedQRImage = qrImage?.tinted(using: color)
        guard let logo = logo?.cgImage else {
            return tintedQRImage
        }
        return tintedQRImage?.combined(with: CIImage(cgImage: logo))
    }

    /// Returns a black and white QR code for this URL.
    var qrImage: CIImage? {
        guard let qrFilter = CIFilter(name: "CIQRCodeGenerator") else { return nil }
        let qrData = absoluteString.data(using: String.Encoding.ascii)
        qrFilter.setValue(qrData, forKey: "inputMessage")
        let qrTransform = CGAffineTransform(scaleX: 12, y: 12)
        return qrFilter.outputImage?.transformed(by: qrTransform)
    }
}

extension CIImage {

    /// Inverts the colors and creates a transparent image by converting the mask to alpha.
    /// Input image should be black and white.
    var transparent: CIImage? {
        return inverted?.blackTransparent
    }

    /// Inverts the colors.
    var inverted: CIImage? {
        guard let invertedColorFilter = CIFilter(name: "CIColorInvert") else { return nil }
        invertedColorFilter.setValue(self, forKey: "inputImage")
        return invertedColorFilter.outputImage
    }

    /// Converts all black to transparent.
    var blackTransparent: CIImage? {
        guard let blackTransparentFilter = CIFilter(name: "CIMaskToAlpha") else { return nil }
        blackTransparentFilter.setValue(self, forKey: "inputImage")
        return blackTransparentFilter.outputImage
    }

    /// Applies the given color as a tint color.
    func tinted(using color: UIColor) -> CIImage?
    {
        guard
            let transparentQRImage = transparent,
            let filter = CIFilter(name: "CIMultiplyCompositing"),
            let colorFilter = CIFilter(name: "CIConstantColorGenerator") else { return nil }

        let ciColor = CIColor(color: color)
        colorFilter.setValue(ciColor, forKey: kCIInputColorKey)
        let colorImage = colorFilter.outputImage
        filter.setValue(colorImage, forKey: kCIInputImageKey)
        filter.setValue(transparentQRImage, forKey: kCIInputBackgroundImageKey)
        return filter.outputImage!
    }

    /// Combines the current image with the given image centered.
    func combined(with image: CIImage) -> CIImage? {
        guard let combinedFilter = CIFilter(name: "CISourceOverCompositing") else { return nil }
        let centerTransform = CGAffineTransform(translationX: extent.midX - (image.extent.size.width / 2), y: extent.midY - (image.extent.size.height / 2))
        combinedFilter.setValue(image.transformed(by: centerTransform), forKey: "inputImage")
        combinedFilter.setValue(self, forKey: "inputBackgroundImage")
        return combinedFilter.outputImage!
    }
}

是的,您几乎完成了

第三步,必须将要显示生成的QRCode的imageview的出口捆绑在一起。

您的 ViewController.swift 文件是这样的。

  // desired color of QRCode
    let OrangeColor = UIColor(red:0.93, green:0.31, blue:0.23, alpha:1.00)
  // app logo or whatever UIImage you want to set in the center.
    let Logo = UIImage(named: "logo_which_you_want_to_set_in_the center_of_the_QRCode")!

    @IBOutlet weak var imgQRImage: UIImageView!

最后一步,最后一步是将QRCode添加到imgQRImage中,并将代码放入您的 viewDidLoad()

override func viewDidLoad() {
    super.viewDidLoad()
    let QRLink = "https://www.peerbits.com/"
    guard let qrURLImage = URL(string: QRLink)?.qrImage(using: self.OrangeColor, logo: self.Logo)else{return}
    self.imgQRImage.image = UIImage(ciImage: qrURLImage)
}

欢呼声

答案 3 :(得分:0)

docs中所述,我们可以使用CIQRCodeGenerator

enter image description here

func qrCode(_ outputSize: CGSize) -> UIImage?
{
    if let data = data(using: .isoLatin1),
       let outputImage = CIFilter(
        name: "CIQRCodeGenerator",
        parameters: [
            "inputMessage": data,
            "inputCorrectionLevel": "Q"
        ]
       )?.outputImage {
        let size: CGRect = outputImage.extent.integral
        
        let format = UIGraphicsImageRendererFormat()
        format.scale = UIScreen.main.scale
        
        return UIGraphicsImageRenderer(size: output, format: format)
            .image { _ in
                outputImage
                    .transformed(
                        by: .init(
                            scaleX: outputSize.width/size.width,
                            y: outputSize.height/size.height
                        )
                    )
                    .uiimage
                    .draw(in: .init(origin: .zero, size: outputSize))
            }

    } else {
        return nil
    }
}

extension CIImage {

   var uiimage: UIImage {
       .init(ciImage: self)
   }
}

这是位modified version of this post

以防万一您需要解析二维码图像中的内容

    func decodeQRCode(_ image: UIImage?) -> [CIQRCodeFeature]? {
        if let image = image,
           let ciImage = CIImage(image: image) {
            
            let context = CIContext()
            var options: [String: Any] = [
                CIDetectorAccuracy: CIDetectorAccuracyHigh
            ]
            
            let qrDetector = CIDetector(
                ofType: CIDetectorTypeQRCode,
                context: context,
                options: options
            )
            
            if ciImage.properties.keys
                .contains((kCGImagePropertyOrientation as String)) {
                options = [
                    CIDetectorImageOrientation: ciImage
                        .properties[(kCGImagePropertyOrientation as String)] as Any
                ]
            } else {
                options = [CIDetectorImageOrientation: 1]
            }
            
            let features = qrDetector?.features(in: ciImage, options: options)
            return features?
                .compactMap({ $0 as? CIQRCodeFeature })
        }
        
        return nil
    }
}