swift之生成条形码、二维码、识别二维码、长按识别二维码

 

===============生成二维码==============

/**
生成二维码,生成条形码
 //    =======生成二维码========
 //
 //    主要用到CIFilter类。CIFilter是Core Image中一个比较核心的有关滤镜使用的类。
 //    通常CIFilter对象需要一个或多个图像作为输入,并产生CIImage类型的实体作为输出。而这些输出图像的生产过程需要我们通过设置一些参数来实现,而这些参数的设置和检索都是利用键/值对的形式进行操作的。
 //    其中CIFlilter承载着所有设置好的滤镜参数以CIImage为基础,在CIContext对象中进行渲染。要提一下的是滤镜的使用是可以叠加的,我们可以使用多种滤镜处理同一个图像。Core Image的渲染分为CPU和GPU两种,其中使用CPU渲染可以在后台进行,但是渲染速度没有GPU快,而GPU是不能进行后台渲染的它是实时的,在进行视频帧渲染时我们就可以使用GPU进行渲染。
 //
 
 使用:
 //不带图片的二维码图片
 let imageViewIcon1 = UIImageView(frame:CGRect(x: 20, y: 100, width: 100, height: 100))
 imageViewIcon1.image = UIViewController.createQRForString(qrString: "https://www.baidu.com", qrImageName: "")
 self.view.addSubview(imageViewIcon1)
 //带图片的二维码图片
 let imageViewIcon2 = UIImageView(frame: CGRect(x: 200, y: 100, width: 100, height: 100))
 imageViewIcon2.image = UIViewController.createQRForString(qrString: "https://www.baidu.com", qrImageName: "appstart")
 self.view.addSubview(imageViewIcon2)
 */

import UIKit

class LYBErweimaExtention: UIViewController {


    

    
override func viewDidLoad() {

    
    }
}

extension UIViewController{
class func createQRForString(qrString: String?, qrImageName: String?) -> UIImage?{
        if let sureQRString = qrString{
            let stringData = sureQRString.data(using: String.Encoding.utf8, allowLossyConversion: false)
            //创建一个二维码的滤镜
            let qrFilter = CIFilter(name: "CIQRCodeGenerator")
            qrFilter?.setValue(stringData, forKey: "inputMessage")
            qrFilter?.setValue("H", forKey: "inputCorrectionLevel")
            let qrCIImage = qrFilter?.outputImage
            // 创建一个颜色滤镜,黑白色
            let colorFilter = CIFilter(name: "CIFalseColor")!
            colorFilter.setDefaults()
            colorFilter.setValue(qrCIImage, forKey: "inputImage")
            colorFilter.setValue(CIColor(red: 0, green: 0, blue: 0), forKey: "inputColor0")
            colorFilter.setValue(CIColor(red: 1, green: 1, blue: 1), forKey: "inputColor1")
            // 返回二维码image
            let codeImage = UIImage(ciImage: (colorFilter.outputImage!.transformed(by: CGAffineTransform(scaleX: 5, y: 5))))
            // 中间一般放logo
            if let iconImage = UIImage(named: qrImageName!) {
                
                let rect = CGRect(x: 0, y: 0, width: codeImage.size.width, height: codeImage.size.height)
                UIGraphicsBeginImageContext(rect.size)
                codeImage.draw(in: rect)
                let avatarSize = CGSize(width: rect.size.width*0.25, height: rect.size.height*0.25)
                let x = (rect.width - avatarSize.width) * 0.5
                let y = (rect.height - avatarSize.height) * 0.5
                iconImage.draw(in: CGRect(x: x, y: y, width: avatarSize.width, height: avatarSize.height))
                let resultImage = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return resultImage
            }
            return codeImage
        }
        return nil
    }
    
    
    
    //生成条形码
class func generateBarCode(messgae:NSString,width:CGFloat,height:CGFloat) -> UIImage {
        var returnImage:UIImage?
        if (messgae.length > 0 && width > 0 && height > 0){
            let inputData:NSData? = messgae.data(using: String.Encoding.utf8.rawValue)! as NSData
            // CICode128BarcodeGenerator
            let filter = CIFilter.init(name: "CICode128BarcodeGenerator")!
            filter.setValue(inputData, forKey: "inputMessage")
            var ciImage = filter.outputImage!
            let scaleX = width/ciImage.extent.size.width
            let scaleY = height/ciImage.extent.size.height
            ciImage = ciImage.transformed(by: CGAffineTransform.init(scaleX: scaleX, y: scaleY))
            returnImage = UIImage.init(ciImage: ciImage)
        }else {
            returnImage = nil;
        }
        return returnImage!
    }
    

}

 

 

=========长按识别二维码=========

 

/**
     ===========长按识别二维码=========
 */
import UIKit

import AVFoundation

import SafariServices

class LYBLongTapErweimaViewController: UIViewController,UIGestureRecognizerDelegate {

    var imageView:UIImageView?
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor=UIColor.white
        navigationItem.title="长按识别"
        longPressRecogErwema()
    }
  func longPressRecogErwema() {
 imageView = UIImageView(frame:CGRect(x: 20, y: 100, width: 100, height: 100))
    imageView!.image = UIViewController.createQRForString(qrString: "https://www.baidu.com", qrImageName: "")
    imageView?.isUserInteractionEnabled=true//这句户一定要打开,否则不能交互
    self.view.addSubview(imageView!)
    
    //长按识别二维码
    let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(QRLongPress(gesture:)))
    longPress.delegate=self
     longPress.minimumPressDuration = 1
    imageView!.addGestureRecognizer(longPress)
     }
    //这个代理需要实现,否则长按手势不识别
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
 //MARK: - 长按二维码识别
    @objc func QRLongPress(gesture: UILongPressGestureRecognizer) {
        if (gesture.state == UIGestureRecognizer.State.began) {
            
            //截图再读取
            UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,true, 0);
            
            let connect:CGContext = UIGraphicsGetCurrentContext()!;
            
            self.view.layer.render(in: connect)
            
            let   image : UIImage  = UIGraphicsGetImageFromCurrentImageContext()!;
            UIGraphicsEndImageContext();
            let  ciImage:CIImage = CIImage.init(cgImage: image.cgImage!)
            let   ciContext:CIContext = CIContext.init(options: [CIContextOption.useSoftwareRenderer:true])//软件渲染
 //1.初始化扫描仪,设置设别类型和识别质量
    let options = [CIDetectorAccuracy : CIDetectorAccuracyHigh]
    let detector: CIDetector = CIDetector.init(ofType: "CIDetectorTypeQRCode", context: ciContext, options: options)!
  //2.扫描获取的特征组
            let features = detector.features(in: ciImage)
            //3.获取扫描结果
     let feature = features[0] as! CIQRCodeFeature
     let scannedResult = feature.messageString
      //4.获取之后的操作---根据扫描结果中的数据进行具体的操作
     print(scannedResult!)
        } else if (gesture.state == UIGestureRecognizer.State.ended) {
            
       }
   }
    
}

===========扫描二维码==============

/**
 扫描二维码
 */
import UIKit

import AVFoundation

import SafariServices

class LYBScanErweimaviewController: UIViewController,AVCaptureMetadataOutputObjectsDelegate{
    //    =========扫描二维码========
    //
    //    参考(二维码生成和识别):http://blog.csdn.net/qq_30970529/article/details/52233292
    //
    //    二维码扫描主要用AVFoundation。AVFoundation是一个很大基础库,用来创建基于时间的视听媒体,可以使用它来检查,创建、编辑或媒体文件。也可以输入流从设备和操作视频实时捕捉和回放。
    //    主要成员介绍:
    //    AVCaptureSession 管理输入(AVCaptureInput)和输出(AVCaptureOutput)流,包含开启和停止会话方法。
    //    AVCaptureDeviceInput 是AVCaptureInput的子类,可以作为输入捕获会话,用AVCaptureDevice实例初始化。
    //    AVCaptureDevice代表了物理捕获设备如:摄像机。用于配置等底层硬件设置相机的自动对焦模式。
    //    AVCaptureMetadataOutput是AVCaptureOutput的子类,处理输出捕获会话。捕获的对象传递给一个委托实现AVCaptureMetadataOutputObjectsDelegate协议。协议方法在指定的派发队列(dispatch queue)上执行。
    //    AVCaptureVideoPreviewLayerCALayer的一个子类,显示捕获到的相机输出流。
    
    
    var session:AVCaptureSession?//会话,用于协调输入输出
    var output:AVCaptureMetadataOutput?//输出
    var input:AVCaptureDeviceInput?//输入
    var layer:AVCaptureVideoPreviewLayer?//特殊的layer,用于展示搜索到的内容---
    var recImageView:UIImageView?//矩形框
    var lineImageView:UIImageView?//闪动的线
    var timer:Timer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor=UIColor.white
        navigationItem.title="扫描二维码"
        saomiaoErweima()
        
    }
    //判断相机的权限
    func testCamera() {
        let authorizationStatus = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
        switch authorizationStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: AVMediaType.video) { (genter) in
                if (genter){
                    print("去打开相机")
                }else{
                    print(">>>访问受限")
                }
            }
            break
        case .authorized:
            print("去打开相机")
            break
        case .restricted:
            print(">>>访问受限")
            break
        case .denied:
            print(">>>访问受限")
            break
        }
    }
    //打开相机扫描
    func saomiaoErweima(){
        //打开相机
        let device=AVCaptureDevice.default(for: AVMediaType.video)
        //创建输入流
        input = try?AVCaptureDeviceInput.init(device: device!)
        //创建输出流
        output=AVCaptureMetadataOutput.init()
        //设置代理在主线程里刷新
        output?.setMetadataObjectsDelegate(self as AVCaptureMetadataOutputObjectsDelegate, queue: DispatchQueue.main
        )
        //设置扫描区域,这个需要仔细调整
//        output?.rectOfInterest=CGRect.init(x: 50, y: 50, width: 200, height: 200)
        //初始化链接对象,连接输入输出
        session=AVCaptureSession.init()
        //高质量采集率
        session?.sessionPreset=AVCaptureSession.Preset.high
        session?.addInput(input!)
        session?.addOutput(output!)
        //设置扫码支持的编码格式
output?.metadataObjectTypes=[AVMetadataObject.ObjectType.qr,AVMetadataObject.ObjectType.ean13,AVMetadataObject.ObjectType.ean8,AVMetadataObject.ObjectType.code128,AVMetadataObject.ObjectType.qr]
        
        layer=AVCaptureVideoPreviewLayer.init(session: session!)
        layer?.videoGravity=AVLayerVideoGravity.resizeAspectFill
        layer?.frame=self.view.layer.bounds
        self.view.layer.addSublayer(layer!)
        setline()//添加扫框
        
        //开始扫描
        session?.startRunning()
    }
    //设置最上面的框和跳动的线
    func setline(){
        //设置背景图片
        recImageView = UIImageView.init(image: UIImage.init(named: "pick_bg.png"))
        //设置位置到界面的中间
        recImageView?.frame = CGRect.init(x: view.bounds.size.width * 0.5 - 140, y: view.bounds.size.height * 0.5 - 140, width: 280, height: 280)
        //添加到视图上
        view.addSubview(recImageView!)
        //初始化二维码的扫描线的位置
        lineImageView=UIImageView.init(image: UIImage.init(named: "line.png"))
        lineImageView?.frame=CGRect.init(x:  self.view.bounds.size.width * 0.5 - 110, y: 10, width: 220, height: 2)
        view.addSubview(lineImageView!)
        //开启定时器
        timer=Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(animate), userInfo: nil, repeats: true)
    }
    @objc func animate() {
        UIView.animate(withDuration: 2, delay: 0, options: UIView.AnimationOptions.curveLinear, animations: {
            self.lineImageView?.frame=CGRect.init(x: self.view.bounds.size.width * 0.5 - 110, y: self.view.bounds.size.height * 0.7, width: 220, height: 2)
        }) { (ist) in
            self.lineImageView?.frame=CGRect.init(x: self.view.bounds.size.width * 0.5 - 110, y: 10, width: 220, height: 2)
        }
    }
//}



/// 实现代理方法--获取数据

//metadataObjects: 扫描到的数据

//fromConnection: 连接

//extension LYBScanErweimaviewController:AVCaptureMetadataOutputObjectsDelegate {
    func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        //停止扫描
        session?.stopRunning()
        //删除特殊的layer
        layer?.removeFromSuperlayer()
        // //3. 获取数据
        //AVMetadataMachineReadableCodeObject:这个类如果不知道,可以打印一下
        let metadataObject = metadataObjects.first as! AVMetadataMachineReadableCodeObject
        var decodeMessage = ""
        switch metadataObject.type {
        case AVMetadataObject.ObjectType.code128:
            // 条形码
            decodeMessage = metadataObject.stringValue!
            break
        case AVMetadataObject.ObjectType.qr:
            // 二维码
            decodeMessage = metadataObject.stringValue!
            break
        case AVMetadataObject.ObjectType.ean13:
            // ISBN书号条码、EAN13码
            decodeMessage = metadataObject.stringValue!
            break
        default:
            break
        }
        print(decodeMessage)
        if(metadataObject.stringValue?.contains("http"))!{
            //4.1 创建SafariVC----如果要打开safari浏览器,需要引入import SafariServices
            let sfvc:SFSafariViewController=SFSafariViewController.init(url: URL.init(string: metadataObject.stringValue!
                )!)
            //4.2 弹出SafariVC
            self.present(sfvc, animated: true, completion: {
            })
        }
    }
}

========包含闪光灯二维码扫描====

https://www.jianshu.com/p/96c40fb6e0b9

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值