扫描二维码控件的封装

效果

源码

https://github.com/YouXianMing/Animations

//
//  QRCodeView.h
//  QRCode
//
//  Created by YouXianMing on 16/7/7.
//  Copyright © 2016年 XianMing You. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
@class QRCodeView;

@protocol QRCodeViewDelegate <NSObject>

@optional

/**
 *  获取QR的扫描结果
 *
 *  @param codeView   QRCodeView实体对象
 *  @param codeString 扫描字符串
 */
- (void)QRCodeView:(QRCodeView *)codeView codeString:(NSString *)codeString;

@end

@interface QRCodeView : UIView

/**
 *  代理
 */
@property (nonatomic, weak) id <QRCodeViewDelegate> delegate;

/**
 *  灯的状态,默认为关闭
 */
@property (nonatomic) AVCaptureTorchMode torchMode;

/**
 *  敏感区域,如果不设置,则为全部扫描区域
 */
@property (nonatomic) CGRect interestArea;

/**
 *  你用来添加自定义控件的view,尺寸与当前初始化的view一致
 */
@property (nonatomic, strong) UIView *contentView;

/**
 *  正在运行当中
 */
@property (nonatomic, readonly) BOOL  isRunning;

/**
 *  开始扫描
 *
 *  @return 如果成功,则返回YES,否则返回NO
 */
- (BOOL)start;

/**
 *  结束扫描
 */
- (void)stop;

@end
//
//  QRCodeView.m
//  QRCode
//
//  Created by YouXianMing on 16/7/7.
//  Copyright © 2016年 XianMing You. All rights reserved.
//

#import "QRCodeView.h"

@interface QRCodeView () <AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic) BOOL                                 isRunning;
@property (nonatomic, strong) UIView                      *videoView;

@property (nonatomic, strong) AVCaptureDeviceInput        *deviceInput;
@property (nonatomic, strong) AVCaptureDevice             *captureDevice;
@property (nonatomic, strong) AVCaptureSession            *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer  *videoPreviewLayer;
@property (nonatomic, strong) AVCaptureMetadataOutput     *captureMetadataOutput;

@end

@implementation QRCodeView

- (instancetype)initWithFrame:(CGRect)frame {

    if (self = [super initWithFrame:frame]) {

        self.videoView = [[UIView alloc] initWithFrame:self.bounds];
        [self addSubview:self.videoView];

        self.contentView = [[UIView alloc] initWithFrame:self.bounds];
        [self addSubview:self.contentView];

        self.captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

        _torchMode = AVCaptureTorchModeOff;

        [self addNotificationCenter];
    }

    return self;
}

#pragma mark - NSNotificationCenter related.

- (void)addNotificationCenter {

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(notificationCenterEvent:)
                                                 name:AVCaptureInputPortFormatDescriptionDidChangeNotification
                                               object:nil];
}

- (void)removeNotificationCenter {

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AVCaptureInputPortFormatDescriptionDidChangeNotification
                                                  object:nil];
}

- (void)notificationCenterEvent:(NSNotification *)sender {

    if (self.interestArea.size.width && self.interestArea.size.height) {

        self.captureMetadataOutput.rectOfInterest = [self.videoPreviewLayer metadataOutputRectOfInterestForRect:self.interestArea];

    } else {

        self.captureMetadataOutput.rectOfInterest = CGRectMake(0, 0, 1, 1);
    }
}

#pragma mark - Start & Stop.

- (BOOL)start {

    // 初始化输入流
    BOOL     result  = NO;
    NSError *error   = nil;
    self.deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:&error];
    if (self.deviceInput == nil) {

        NSLog(@"%@", error);
        return result;
    }

    // 创建会话
    self.captureSession = [[AVCaptureSession alloc] init];

    // 添加输入流
    [self.captureSession addInput:self.deviceInput];

    // 初始化输出流
    self.captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];

    // 添加输出流
    [self.captureSession addOutput:self.captureMetadataOutput];

    // 创建queue.
    [self.captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatch_queue_create(nil, nil)];
    self.captureMetadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode];

    // 创建输出对象
    self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
    self.videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    self.videoPreviewLayer.frame = self.contentView.bounds;
    [self.videoView.layer addSublayer:self.videoPreviewLayer];

    // 开始
    [self.captureSession startRunning];
    self.isRunning = YES;
    result         = YES;

    return result;
}

- (void)stop {

    [self.captureSession stopRunning];
    self.isRunning      = NO;
    self.captureSession = nil;
}

#pragma mark - AVCaptureMetadataOutputObjectsDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects
       fromConnection:(AVCaptureConnection *)connection {

    if (metadataObjects.count > 0) {

        AVMetadataMachineReadableCodeObject *metadata = metadataObjects.firstObject;
        NSString                            *result   = nil;

        if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {

            result = metadata.stringValue;

            if (_delegate && [_delegate respondsToSelector:@selector(QRCodeView:codeString:)]) {

                [_delegate QRCodeView:self codeString:result];
            }
        }
    }
}

#pragma mark - Setter & Getter.

- (void)setTorchMode:(AVCaptureTorchMode)torchMode {

    _torchMode = torchMode;

    if (_deviceInput && [self.captureDevice hasTorch]) {

        [self.captureDevice lockForConfiguration:nil];
        [self.captureDevice setTorchMode:torchMode];
        [self.captureDevice unlockForConfiguration];
    }
}

#pragma mark - System method.

- (void)dealloc {

    [self stop];
    [self removeNotificationCenter];
}

@end
时间: 2024-10-12 04:40:13

扫描二维码控件的封装的相关文章

在DevExpress程序中使用条形码二维码控件,以及进行报表打印处理

在很多业务系统里面,越来越多涉及到条形码.二维码的应用了,不管在Web界面还是WInform界面都需要处理很多物料相关的操作,甚至很多企业为了减少录入错误操作,为每个设备进行条形码.二维码的标签,直接在流程中进行扫描处理,仅仅在界面勾选一些处理选项即可,极大提高工作效率,降低出错的几率.本篇随笔介绍如何在基于WInform的DevExpress程序中对条形码.二维码的处理,包括界面展示,报表打印等常规的处理. 1.DevExpress的条形码操作及报表打印 在15.1以上的DevEpxress版

使用vue做移动app时,调用摄像头扫描二维码

现在前端技术发展飞快,前端都能做app了,那么项目中,也会遇到调用安卓手机基层的一些功能,比如调用摄像头,完成扫描二维码功能 下面我就为大家讲解一下,我在项目中调用这功能的过程. 首先我们需要一个中间框架,hbuilder http://www.html5plus.org/doc/zh_cn/accelerometer.html 这个是html5+的文档地址,我们找到Barcode模块, 有这么多,然后我们往下找 找到这段代码 <!DOCTYPE html> <html> <

phonegap安卓环境下使用BarcodeScanner插件扫描二维码教程

由于一直在使用phoneGap来开发安卓应用,而对于原生Java小白的我最近这几天一直陷入了如何使用phonegap的BarcodeScanner插件这件事情上,可以说查遍了百度和Google,虽然只是一个小小的二维码的功能,但是这里面还是让我学到了许多开发安卓应用的内容,一起共勉吧. 首先,告诉大家的是 1.我使用的phonegap版本是2.9.0,当然对于phonegap版本的东西我也不太了解,不过可以保证的是phonegap2.0.0之后的按照我这种办法来实现二维码是没有问题的. 2.ph

在WPF中开启摄像头扫描二维码(Media+Zxing)

原文:在WPF中开启摄像头扫描二维码(Media+Zxing) 近两天项目中需要添加一个功能,是根据摄像头来读取二维码信息,然后根据读出来的信息来和数据库中进行对比显示数据. 选择技术Zxing.WPFMediaKit.基本的原理就是让WPFmediaKit来对摄像头进行操作,然后Zxing这个库对图片进行分析大致就是这样. 在后台中定义了定时器,用于解析当前摄像头的图像,然后直接读数据. 需要注意的是一定要引入 using WPFMediaKit.DirectShow.Controls; us

java实现手机扫描二维码进行登录

转自:http://www.daxueit.com/article/2581.html 项目结构: 实现流程: pc端: 1:打开二维码登录网页index.html 2:index.html调用GetQrCodeServlet 3:GetQrCodeServlet干2件事 a:生成随机的uuid,是一个唯一标识,该标识贯穿整个流程 b:生成二维码图片,二维码信息:http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid 4:

android 利用ZXING扫描二维码代码分析

之前给公司做了一个摄影相关的应用,现在要添加二维码扫描的功能,网上找资料后,虽然已经成功集成到app里面,但是总感觉心里没底儿.所以趁这段时间不是很忙,总结一下. 首先是启动扫描的UI类: 1,Activity启动,当然是onCreate方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

微信内点击链接或扫描二维码直接打开手机默认浏览器打开指定网页

需求分析 将打包好的apk/ios文件部署到服务器,把下载页面的URL通过二维码编辑器或根据URL代码生成一个二维码,然后通过二维码进行微信推广已经成为很多用户惯用的方式.但微信会对含apk/ios文件的链接进行了屏蔽,所以导致微信扫码打不开下载链接.理想的状态是安卓自动下载,苹果点击左上角按钮前往Safari下载.那么究竟该如何处理才能达到理想的结果呢? 我们知道 js 可以通过 window.navigator.userAgent 来获取浏览器的相关信息,比如:Mozilla/5.0 (Wi

PHP微信扫描二维码登录网站代码示例

扫描二维码登录对于现在的web应用来说,确实是个很炫酷的功能,安全性也可以保障,不少朋友可能觉得这是个很复杂的工作,其实不然,真正说来只有几个步骤而已. 原理 PC浏览器展示一张二维码图片,该图片二维码值为一段绝对地址的url,大致如下:http://www.example.com/oauth/qrcode?key=key PC浏览器定期轮询 http://www.example.com/oauth/query,可能有的同学会问,怎么不用带上key?这里我们用session来保存key,所以链接

完美解决Android使用Zxing扫描二维码改成竖屏后,后面的预览画面出现了拉伸,扭曲的情况

完美解决解决Android使用Zxing扫描二维码改成竖屏后,后面的预览画面出现了拉伸,扭曲的情况 第一步:找到com.zxing.camera包下的CameraConfigurationManager.java文件中的void initFromCameraParameters(Camera camera)方法 第二步:在 Log.d(TAG, "Screen resolution: " + screenResolution);后加上如下的代码 Point screenResoluti