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
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章