不积跬步,无以至千里;不积小流,无以成江海
在生活中随处可见二维码,特别是支付宝支付和微信支付把二维码推向了高潮。现在在项目也要添加二维码扫描功能
初期规划的功能只是扫描墙上或者设备上的二维码,所以也只做了最简单的二维码扫描。
后来在实际使用过程中发现有其他场景,比如:在大屏幕上有个二维码,你坐在座位上扫的时候发现扫不上。这时候就需要扫描范围放大来识别二维码。
对标微信的扫一扫,可能没有那么好的性能,但是功能上可以是一致的
双击放大:
-(void)handleDoubleTap:(UITapGestureRecognizer *)recogniser {
if (!_device)
return;
if (recogniser.state == UIGestureRecognizerStateBegan)
{
_initialPinchZoom = _device.videoZoomFactor;
}
NSError *error = nil;
[_device lockForConfiguration:&error];
if (!error) {
CGFloat zoomFactor;
if (_device.videoZoomFactor == 1.0f) {
zoomFactor = _maxZoom;
}
else{
zoomFactor = 1.0f;
}
_device.videoZoomFactor = zoomFactor;
[_device unlockForConfiguration];
}
}
两指缩放:
- (void)pinchDetected:(UIPinchGestureRecognizer *)recogniser {
if (!_device)
return;
if (recogniser.state == UIGestureRecognizerStateBegan)
{
_initialPinchZoom = _device.videoZoomFactor;
}
NSError *error = nil;
[_device lockForConfiguration:&error];
if (!error) {
CGFloat zoomFactor;
CGFloat scale = recogniser.scale;
zoomFactor = scale * _initialPinchZoom;
zoomFactor = MIN(_maxZoom, zoomFactor);
zoomFactor = MAX(1.0f, zoomFactor);
_device.videoZoomFactor = zoomFactor;
[_device unlockForConfiguration];
NSLog(@"%f",_device.videoZoomFactor);
}
}
单击屏幕对焦:
//手动对焦
- (void)focusGesture:(UITapGestureRecognizer*)gesture{
CGPoint point = [gesture locationInView:gesture.view];
[self focusAtPoint:point];
}
- (void)focusAtPoint:(CGPoint)point{
CGSize size = self.view.bounds.size;
CGPoint focusPoint = CGPointMake( point.y /size.height ,1-point.x/size.width );
NSError *error;
if ([self.device lockForConfiguration:&error]) {
if ([self.device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
[self.device setFocusPointOfInterest:focusPoint];
[self.device setFocusMode:AVCaptureFocusModeAutoFocus];
}
if ([self.device isExposureModeSupported:AVCaptureExposureModeAutoExpose ]) {
[self.device setExposurePointOfInterest:focusPoint];
[self.device setExposureMode:AVCaptureExposureModeAutoExpose];
}
[self.device unlockForConfiguration];
_focusView.center = point;
_focusView.hidden = NO;
[UIView animateWithDuration:0.3 animations:^{
_focusView.transform = CGAffineTransformMakeScale(1.25, 1.25);
}completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{
_focusView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
_focusView.hidden = YES;
}];
}];
}
}
注意:
在点击对焦后,它锁定你点击的焦点对焦,锁定当前焦距,摄像头切换到其他地方,发现变模糊了,这是因为还是之前的焦距。这时候需要监听摄像头位置改变“AVCaptureDeviceSubjectAreaDidChangeNotification”,将摄像头切换为连续对焦模式。
1.打开设备的监听
device.subjectAreaChangeMonitoringEnabled=YES;
2.添加通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(subjectAreaDidChange:)name:AVCaptureDeviceSubjectAreaDidChangeNotification object:self.device];
3.修改对焦模式
- (void)subjectAreaDidChange:(NSNotification *)notification
{
if (_device.focusMode == AVCaptureFocusModeContinuousAutoFocus) {
return;
}
//先进行判断是否支持控制对焦
if (_device.isFocusPointOfInterestSupported &&[_device isFocusModeSupported:AVCaptureFocusModeAutoFocus]) {
NSError *error =nil;
//对cameraDevice进行操作前,需要先锁定,防止其他线程访问,
[_device lockForConfiguration:&error];
//自动对焦
[_device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[_device setFocusPointOfInterest:CGPointMake(0.5, 0.5)];
//自动曝光
[_device setExposureMode:(AVCaptureExposureModeContinuousAutoExposure)];
[_device setExposurePointOfInterest:CGPointMake(0.5, 0.5)];
// [self focusAtPoint:CGPointMake(ScreenWidth/2, ScreenHeight/2 - 32.5*SCALE)];
//操作完成后,记得进行unlock。
[_device unlockForConfiguration];
}
}
总结:
这样一个具有缩放功能的二维码扫描基本完善了。微信的扫一扫可以自动识别二维码,并放大识别,对焦后也更加流畅。这就是我们和微信的差距吧。
最后放上git地址:https://github.com/famile/QRCodeScanDemo
跑得慢,听到的是骂声; 跑得快,听到的就只是风声