===============生成二维码==============
/**
生成二维码,生成条形码
// =======生成二维码========
//
// 主要用到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: {
})
}
}
}
========包含闪光灯二维码扫描====