iOS 生成二维码(Swift)

public enum CodeDescriptor: String {
    case qrCpde = "CIQRCodeGenerator"
    //只能识别 ascii characters
    case code128Barcod = "CICode128BarcodeGenerator"
    //显示中文会乱码
    case pdf417 = "CIPDF417BarcodeGenerator"
    //显示中文会乱码
    case aztec = "CIAztecCodeGenerator"
}

enum CodeKey:String{
    ///设置内容
    case inputMessage = "inputMessage"
    ///设置容错级别
    case inputCorrectionLevel = "inputCorrectionLevel"
}

///  容错级别

/*

 qrCpde 和 pdf417

 inputCorrectionLevel 是一个单字母(@"L", @"M", @"Q", @"H" 中的一个),表示不同级别的容错率,默认为 @"M"

 QR码有容错能力,QR码图形如果有破损,仍然可以被机器读取内容,最高可以到7%~30%面积破损仍可被读取

 相对而言,容错率愈高,QR码图形面积愈大。所以一般折衷使用15%容错能力。错误修正容量 L水平 7%的字码可被修正

 M水平 15%的字码可被修正

 Q水平 25%的字码可被修正

 H水平 30%的字码可被修正

 code128Barcod 不能设置inputCorrectionLevel属性

 aztec inputCorrectionLevel 5 - 95

 */

public  enum  CorrectionLevel{
      case L
      case M
      case Q
      case H
      case aztecLevel(_ value:Int)
      var  levelValue:String{
         switch self {
            case .L:
                return "L"
            case .M:
                return "M"
            case .Q:
                return "Q"
            case .H:
                return "H"
            default:return  "" }
 }
}

生成二维码

/// 生成对应的码图片
    /// - Parameters:
    ///   - string: 图片中的内容
    ///   - descriptor: 码的类型
    ///   - size: 图片的大小
    ///   - color: 图片的颜色
    ///   - level: 码的容错级别
    /// - Returns: 图片
    open class func generate(string: String,descriptor: CodeDescriptor,size: CGSize,color:UIColor? = nil,level:CorrectionLevel = .M) -> UIImage? {
        guard let data = string.data(using: .utf8),let filter = CIFilter(name: descriptor.rawValue) else {
            return nil
        }
        
        filter.setValue(data, forKey: CodeKey.inputMessage.rawValue)
        if (descriptor == .qrCpde || descriptor == .pdf417){
            switch level {
            case .L,.M,.Q,.H:
                filter.setValue(level.levelValue, forKey: CodeKey.inputCorrectionLevel.rawValue)
            default:break
            }
        }else if descriptor == .aztec{
            switch level {
            case .aztecLevel(var value):
                if value < 5 {
                    value = 5
                }else if value > 95{
                    value = 95
                }
                filter.setValue(NSNumber.init(value: value), forKey: CodeKey.inputCorrectionLevel.rawValue)
            default:break
            }
        }
        
        guard let image = filter.outputImage else {
            return nil
        }
        
        let imageSize = image.extent.size
        let transform = CGAffineTransform(scaleX: size.width / imageSize.width,y: size.height / imageSize.height)
        let scaledImage = image.transformed(by: transform)
        
        guard let codeColor = color else{
            return UIImage.init(ciImage: scaledImage)
        }
        
        // 设置颜色
        let colorFilter = CIFilter(name: "CIFalseColor", parameters: ["inputImage":scaledImage,"inputColor0":CIColor(cgColor: codeColor.cgColor ),"inputColor1":CIColor(cgColor: UIColor.clear.cgColor)])
        
        guard let newOutPutImage = colorFilter?.outputImage else {
            return UIImage.init(ciImage: scaledImage)
        }
        
        return UIImage.init(ciImage: newOutPutImage)
    }

给二维码中间添加icon

 /// 根码上夹图片
    /// - Parameters:
    ///   - inputImage: 码图片
    ///   - fillImage: 中间的icon图片
    ///   - fillSize: icon的大小
    /// - Returns: 合成后的图片
    open class func fillImage(_ inputImage:UIImage?,_ fillImage:UIImage?,_ fillSize:CGSize) -> UIImage? {
        guard let input = inputImage,let fill = fillImage  else {
            return inputImage
        }
        let imageSize = input.size
        UIGraphicsBeginImageContext(imageSize)
        input.draw(in: CGRect.init(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
        let fillWidth = min(imageSize.width, fillSize.width)
        let fillHeight = min(imageSize.height, fillSize.height)
        let fillRect = CGRect(x: (imageSize.width - fillWidth)/2, y: (imageSize.height - fillHeight)/2, width: fillWidth ,height: fillHeight)
        fill.draw(in: fillRect)
        guard let newImage = UIGraphicsGetImageFromCurrentImageContext() else {
            UIGraphicsEndImageContext()
            return inputImage
        }
        UIGraphicsEndImageContext()
        return newImage
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章