import UIKit
import AVFoundation
let kScreenWidth:CGFloat = UIScreen.main.bounds.width
let kScreenHeight:CGFloat = UIScreen.main.bounds.height
class ViewController: UIViewController {
@IBOutlet weak var scanHeightConst: NSLayoutConstraint!
@IBOutlet weak var scanTopConst: NSLayoutConstraint!
@IBOutlet weak var resultLabel: UIButton!
/// 专门用于保存描边的图层
private lazy var containerLayer: CALayer = CALayer()
private lazy var session: AVCaptureSession = {
let session = AVCaptureSession()
return session
}()
private lazy var previewLayer: AVCaptureVideoPreviewLayer = {
let previewLayer = AVCaptureVideoPreviewLayer(session: session)
previewLayer.frame = view.bounds
return previewLayer
}()
override func viewDidLoad() {
super.viewDidLoad()
scan()
}
override func viewDidAppear(_ animated: Bool){
super.viewWillAppear(animated)
/**
whose view is not in the window hierarchy!
*/
cammerRoot()
scanAnimation()
}
private func scanAnimation(){
scanTopConst.constant = -scanHeightConst.constant
view.layoutIfNeeded()
UIView.animate(withDuration: 2.0) {
UIView.setAnimationRepeatCount(MAXFLOAT)
self.scanTopConst.constant = self.scanHeightConst.constant
// self.scanImageView.layer.masksToBounds = true
self.view.layoutIfNeeded()
}
}
//扫描
private func scan(){
guard let device = AVCaptureDevice.default(for: AVMediaType.video) else{
print("设备失败")
return
}
guard let input = try? AVCaptureDeviceInput(device: device) else{
print("输入设备失败")
return
}
let output = AVCaptureMetadataOutput()
if !session.canAddInput(input) {
return
}
if !session.canAddOutput(output) {
return
}
// 3.添加输入和输出到会话中(老是忘记就会导致界面啥都没有)
session.addInput(input)
session.addOutput(output)
output.metadataObjectTypes = output.availableMetadataObjectTypes
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
//设置可扫描区域
let redView = UIView(frame: CGRect(x: 0, y: 0, width: 240, height: 240))
redView.center = view.center
print(redView.frame)//(40.0, 164.0, 240.0, 240.0)
redView.layer.borderWidth = 2
redView.layer.borderColor = UIColor.red.cgColor
view.addSubview(redView)
output.rectOfInterest = CGRect(x:redView.frame.origin.y/kScreenHeight , y: (kScreenWidth - redView.frame.origin.x - 240)/kScreenWidth, width: 240/kScreenHeight, height: 240/kScreenWidth)
print(output.rectOfInterest) //(0.0704225352112676, 0.125, 0.422535211267606, 0.75)
view.layer.insertSublayer(previewLayer, at: 0)
session.startRunning()
}
//权限访问
private func cammerRoot(){
let mediaType = AVMediaType.video
let authStatus = AVCaptureDevice.authorizationStatus(for: mediaType)
if authStatus == AVAuthorizationStatus.restricted || authStatus == AVAuthorizationStatus.denied || authStatus == AVAuthorizationStatus.notDetermined {
let alertViewController = UIAlertController(title: "权限", message: "请在iPhone的“设置”-“隐私”-“相机”功能中,找到“项目名称”打开相机访问权限", preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "取消", style: .cancel, handler: { (alerAction: UIAlertAction) in
})
let sureAction = UIAlertAction(title: "设置", style: .destructive, handler: { (sureAction: UIAlertAction) in
guard let url = URL.init(string: "prefs:root=Privacy&path=CAMERA") else{
print("url为空")
return
}
if #available(iOS 10.0, *) {
if UIApplication.shared.canOpenURL(url){
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
} else {
// Fallback on earlier versions
if UIApplication.shared.canOpenURL(url){
UIApplication.shared.canOpenURL(url)
}
}
})
alertViewController.addAction(cancelAction)
alertViewController.addAction(sureAction)
present(alertViewController, animated: true, completion: nil)
}else{
print("有权限")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
extension ViewController: AVCaptureMetadataOutputObjectsDelegate{
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if metadataObjects.count > 0 {
session.stopRunning()
}
let lastObjc:AVMetadataMachineReadableCodeObject = metadataObjects.last as! AVMetadataMachineReadableCodeObject
let finalResult = lastObjc.stringValue
//显示结果
resultLabel.setTitle(finalResult, for: .normal)
// 通过预览图层将corners值转换为我们能识别的类型
let metaObj = previewLayer.transformedMetadataObject(for: metadataObjects.last!)
}
}
result.png
坐标转换.png
- (void)viewDidLoad {
[super viewDidLoad];
UIImage * img = [self qrCodeImageWithInfo:@"http:www.baidu.com" width:150];
UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 150, 35)];
imgView.center = self.view.center;
imgView.image = img;
[self.view addSubview:imgView];
}
- (UIImage *)qrCodeImageWithInfo:(NSString *)info width:(CGFloat)width
{
if (!info) {
return nil;
}
NSData *strData = [info dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
//创建二维码滤镜
CIFilter *qrFilter = [CIFilter filterWithName:@"CICode128BarcodeGenerator"];
[qrFilter setValue:strData forKey:@"inputMessage"];
CIImage *qrImage = qrFilter.outputImage;
//颜色滤镜
CIFilter *colorFilter = [CIFilter filterWithName:@"CIFalseColor"];
[colorFilter setDefaults];
[colorFilter setValue:qrImage forKey:kCIInputImageKey];
[colorFilter setValue:[CIColor colorWithRed:0 green:0 blue:0] forKey:@"inputColor0"];
CIImage *colorImage = colorFilter.outputImage;
//返回二维码
// CGFloat scale = width/31;
// UIImage *codeImage = [UIImage imageWithCIImage:[colorImage imageByApplyingTransform:CGAffineTransformMakeScale(scale, scale)]];
// UIImage *codeImage = [UIImage imageWithCIImage:colorImage];//返回普通条形码
UIImage *codeImage = [self getErWeiMaImageFormCIImage:colorImage withSize:150];//高清条码
return codeImage;
}
- (UIImage *)getErWeiMaImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 1.创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 2.保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
return [UIImage imageWithCGImage:scaledImage];
}
- (void)viewDidLoad {
[super viewDidLoad];
CIImage * CIImg = [self createQRForString:@"http:www.baidu.com"];
UIImage * img = [self createNonInterpolatedUIImageFormCIImage:CIImg withSize:150];
UIImageView * imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 150, 150)];
imgView.center = self.view.center;
imgView.image = img;
[self.view addSubview:imgView];
}
- (CIImage *)createQRForString:(NSString *)qrString {
NSData *stringData = [qrString dataUsingEncoding:NSUTF8StringEncoding];
// 创建filter
CIFilter *qrFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
// 设置内容
[qrFilter setValue:stringData forKey:@"inputMessage"];
[qrFilter setValue:@"M" forKey:@"inputCorrectionLevel"];//纠错级别
// 返回CIImage
return qrFilter.outputImage;
}
- (UIImage *)createNonInterpolatedUIImageFormCIImage:(CIImage *)image withSize:(CGFloat) size {
CGRect extent = CGRectIntegral(image.extent);
CGFloat scale = MIN(size/CGRectGetWidth(extent), size/CGRectGetHeight(extent));
// 1.创建bitmap;
size_t width = CGRectGetWidth(extent) * scale;
size_t height = CGRectGetHeight(extent) * scale;
CGColorSpaceRef cs = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapRef = CGBitmapContextCreate(nil, width, height, 8, 0, cs, (CGBitmapInfo)kCGImageAlphaNone);
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef bitmapImage = [context createCGImage:image fromRect:extent];
CGContextSetInterpolationQuality(bitmapRef, kCGInterpolationNone);
CGContextScaleCTM(bitmapRef, scale, scale);
CGContextDrawImage(bitmapRef, extent, bitmapImage);
// 2.保存bitmap到图片
CGImageRef scaledImage = CGBitmapContextCreateImage(bitmapRef);
CGContextRelease(bitmapRef);
CGImageRelease(bitmapImage);
//原图
UIImage *outputImage = [UIImage imageWithCGImage:scaledImage];
UIGraphicsBeginImageContextWithOptions(outputImage.size, NO, [[UIScreen mainScreen] scale]);
[outputImage drawInRect:CGRectMake(0,0 , size, size)];
//水印图
UIImage *waterimage = [UIImage imageNamed:@"缴费信息"];
UIImageView * imageView = [[UIImageView alloc] initWithImage:waterimage];
[waterimage drawInRect:CGRectMake((size- imageView.bounds.size.width)/2.0, (size-imageView.bounds.size.width)/2.0, imageView.bounds.size.width, imageView.bounds.size.height)];
UIImage *newPic = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newPic;
}
Simulator Screen Shot - iPhone 8 Plus - 2018-03-14 at 15.33.18.png
网友评论