@@ -10,12 +10,10 @@ @implementation ScannerViewController {
10
10
AVCaptureDevice *_device;
11
11
AVCaptureVideoPreviewLayer *_prevLayer;
12
12
bool running;
13
- NSString * lastFormat;
14
-
13
+ NSString *lastFormat;
15
14
MainScreenState state;
16
-
17
- CGImageRef decodeImage;
18
- NSString * decodeResult;
15
+ CGImageRef decodeImage;
16
+ NSString *decodeResult;
19
17
size_t width;
20
18
size_t height;
21
19
size_t bytesPerRow;
@@ -32,7 +30,7 @@ @implementation ScannerViewController {
32
30
33
31
- (void ) viewWillAppear : (BOOL )animated {
34
32
[super viewWillAppear: animated];
35
-
33
+
36
34
#if TARGET_IPHONE_SIMULATOR
37
35
NSLog (@" IDScanner: On iOS simulator camera is not supported" );
38
36
[self .delegate returnScanResult: self scanResult: nil ];
@@ -51,7 +49,7 @@ - (void)viewWillDisappear:(BOOL) animated {
51
49
52
50
- (void )viewDidLoad {
53
51
[super viewDidLoad ];
54
-
52
+
55
53
self.prevLayer = nil ;
56
54
[[NSNotificationCenter defaultCenter ] addObserver: self selector: @selector (decodeResultNotification: ) name: DecoderResultNotification object: nil ];
57
55
}
@@ -83,10 +81,10 @@ - (void)toggleTorch
83
81
[self .device setTorchMode: AVCaptureTorchModeOff];
84
82
else
85
83
[self .device setTorchMode: AVCaptureTorchModeOn];
86
-
84
+
87
85
if ([self .device isFocusModeSupported: AVCaptureFocusModeContinuousAutoFocus])
88
86
self.device .focusMode = AVCaptureFocusModeContinuousAutoFocus;
89
-
87
+
90
88
[self .device unlockForConfiguration ];
91
89
}
92
90
}
@@ -95,7 +93,7 @@ - (void)toggleTorch
95
93
- (void )initCapture
96
94
{
97
95
self.device = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeVideo];
98
-
96
+
99
97
if (@available (iOS 13.0 , *)) {
100
98
AVCaptureDeviceDiscoverySession *captureDeviceDiscoverySession = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes: @[AVCaptureDeviceTypeBuiltInUltraWideCamera]
101
99
mediaType: AVMediaTypeVideo
@@ -105,32 +103,31 @@ - (void)initCapture
105
103
106
104
if (captureDevices.count > 0 ) {
107
105
NSLog (@" Supports ultrawide camera" );
108
-
106
+
109
107
self.device = captureDevices[0 ];
110
108
}
111
109
}
112
110
113
-
114
111
AVCaptureDeviceInput *captureInput = [AVCaptureDeviceInput deviceInputWithDevice: self .device error: nil ];
115
112
AVCaptureVideoDataOutput *captureOutput = [[AVCaptureVideoDataOutput alloc ] init ];
116
113
captureOutput.alwaysDiscardsLateVideoFrames = YES ;
117
114
[captureOutput setSampleBufferDelegate: self queue: dispatch_get_main_queue ()];
118
-
115
+
119
116
// Set the video output to store frame in BGRA (It is supposed to be faster)
120
117
NSString * key = (NSString *)kCVPixelBufferPixelFormatTypeKey ;
121
-
118
+
122
119
// Set the video output to store frame in 422YpCbCr8(It is supposed to be faster)
123
120
NSNumber * value = [NSNumber numberWithUnsignedInt: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ];
124
121
NSDictionary * videoSettings = [NSDictionary dictionaryWithObject: value forKey: key];
125
122
[captureOutput setVideoSettings: videoSettings];
126
-
123
+
127
124
// Create a capture session
128
125
self.captureSession = [[AVCaptureSession alloc ] init ];
129
-
126
+
130
127
// We add input and output
131
128
[self .captureSession addInput: captureInput];
132
129
[self .captureSession addOutput: captureOutput];
133
-
130
+
134
131
if ([self .captureSession canSetSessionPreset: AVCaptureSessionPreset1280x720]) {
135
132
NSLog (@" Set preview port to 1280X720" );
136
133
self.captureSession .sessionPreset = AVCaptureSessionPreset1280x720;
@@ -140,61 +137,45 @@ - (void)initCapture
140
137
NSLog (@" Set preview port to 640X480" );
141
138
self.captureSession .sessionPreset = AVCaptureSessionPreset640x480;
142
139
}
143
-
144
- // Limit camera FPS to 15 for single core devices (iPhone 4 and older) so more CPU power is available for decoder
145
- host_basic_info_data_t hostInfo;
146
- mach_msg_type_number_t infoCount;
147
- infoCount = HOST_BASIC_INFO_COUNT;
148
- host_info (mach_host_self (), HOST_BASIC_INFO, (host_info_t )&hostInfo, &infoCount);
149
-
150
- if (hostInfo.max_cpus < 2 ) {
151
- if ([self .device respondsToSelector: @selector (setActiveVideoMinFrameDuration: )]) {
152
- [self .device lockForConfiguration: nil ];
153
- [self .device setActiveVideoMinFrameDuration: CMTimeMake (1 , 15 )];
154
- [self .device unlockForConfiguration ];
155
- } else {
156
- AVCaptureConnection *conn = [captureOutput connectionWithMediaType: AVMediaTypeVideo];
157
- [conn setVideoMinFrameDuration: CMTimeMake (1 , 15 )];
158
- }
159
- }
160
-
140
+
161
141
// We add the preview layer
162
142
self.prevLayer = [AVCaptureVideoPreviewLayer layerWithSession: self .captureSession];
163
-
164
- if (self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
143
+
144
+ UIInterfaceOrientation orientation = [UIApplication sharedApplication ].statusBarOrientation ;
145
+ if (orientation == UIInterfaceOrientationLandscapeLeft) {
165
146
self.prevLayer .connection .videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
166
147
self.prevLayer .frame = CGRectMake (0 , 0 , MAX (self.view .frame .size .width ,self.view .frame .size .height ), MIN (self.view .frame .size .width ,self.view .frame .size .height ));
167
148
}
168
- if (self. interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
149
+ if (orientation == UIInterfaceOrientationLandscapeRight) {
169
150
self.prevLayer .connection .videoOrientation = AVCaptureVideoOrientationLandscapeRight;
170
151
self.prevLayer .frame = CGRectMake (0 , 0 , MAX (self.view .frame .size .width ,self.view .frame .size .height ), MIN (self.view .frame .size .width ,self.view .frame .size .height ));
171
152
}
172
-
173
- if (self. interfaceOrientation == UIInterfaceOrientationPortrait) {
153
+
154
+ if (orientation == UIInterfaceOrientationPortrait) {
174
155
self.prevLayer .connection .videoOrientation = AVCaptureVideoOrientationPortrait;
175
156
self.prevLayer .frame = CGRectMake (0 , 0 , MIN (self.view .frame .size .width ,self.view .frame .size .height ), MAX (self.view .frame .size .width ,self.view .frame .size .height ));
176
157
}
177
- if (self. interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
158
+ if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
178
159
self.prevLayer .connection .videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
179
160
self.prevLayer .frame = CGRectMake (0 , 0 , MIN (self.view .frame .size .width ,self.view .frame .size .height ), MAX (self.view .frame .size .width ,self.view .frame .size .height ));
180
161
}
181
-
162
+
182
163
self.prevLayer .videoGravity = AVLayerVideoGravityResizeAspectFill;
183
164
[self .view.layer addSublayer: self .prevLayer];
184
165
#if USE_MWOVERLAY
185
166
[MWOverlay addToPreviewLayer: self .prevLayer];
186
167
#endif
187
168
188
169
self.focusTimer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self selector: @selector (reFocus ) userInfo: nil repeats: YES ];
189
-
170
+
190
171
[self CustomOverlay ];
191
172
}
192
173
193
174
- (void ) CustomOverlay
194
175
{
195
176
CGRect bounds = self.view .bounds ;
196
177
bounds = CGRectMake (0 , 0 , bounds.size .width , bounds.size .height );
197
-
178
+
198
179
UIView* overlayView = [[UIView alloc ] initWithFrame: bounds];
199
180
overlayView.autoresizesSubviews = YES ;
200
181
overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
@@ -239,7 +220,7 @@ - (void) onVideoStart: (NSNotification*) note
239
220
return ;
240
221
}
241
222
running = YES ;
242
-
223
+
243
224
// lock device and set focus mode
244
225
NSError *error = nil ;
245
226
if ([self .device lockForConfiguration: &error]) {
@@ -271,23 +252,21 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput
271
252
if (self.state != CAMERA_DECODING) {
272
253
self.state = CAMERA_DECODING;
273
254
}
274
-
255
+
275
256
CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer (sampleBuffer);
276
-
277
- // get image
278
257
CIImage *ciImage = [CIImage imageWithCVPixelBuffer: imageBuffer];
279
-
258
+
280
259
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
281
260
NSUserDefaults *settings = [NSUserDefaults standardUserDefaults ];
282
-
261
+
283
262
// activate license
284
263
NSString *scannerType = [settings objectForKey: @" scannerType" ];
285
-
264
+
286
265
IDScanPDFDetector *pdfDetector = [IDScanPDFDetector detectorWithActivationKey: [settings objectForKey: @" scannerPDFKey" ]];
287
266
IDScanMRZDetector *mrzDetector = [IDScanMRZDetector detectorWithActivationKey: [settings objectForKey: @" scannerMRZKey" ]];
288
-
267
+
289
268
NSString *result = @" " ;
290
-
269
+
291
270
// detect based on scanner Type
292
271
if ([scannerType isEqualToString: @" pdf" ]) {
293
272
result = [pdfDetector detectFromImage: ciImage][@" string" ];
@@ -296,19 +275,19 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput
296
275
} else {
297
276
// combined scanner
298
277
result = [pdfDetector detectFromImage: ciImage][@" string" ];
299
-
278
+
300
279
if ([result length ] < 4 ) {
301
280
result = [mrzDetector detectFromImage: ciImage][@" string" ];
302
281
}
303
282
}
304
-
283
+
305
284
// Ignore results less than 4 characters - probably false detection
306
285
if ([result length ] > 4 ) {
307
286
self.state = CAMERA;
308
-
309
- if (decodeImage != nil ) {
310
- CGImageRelease (decodeImage);
311
- decodeImage = nil ;
287
+
288
+ if (self-> decodeImage != nil ) {
289
+ CGImageRelease (self-> decodeImage );
290
+ self-> decodeImage = nil ;
312
291
}
313
292
314
293
dispatch_async (dispatch_get_main_queue (), ^(void ) {
@@ -322,18 +301,17 @@ - (void)captureOutput:(AVCaptureOutput *)captureOutput
322
301
self.state = CAMERA;
323
302
}
324
303
});
325
-
326
304
}
327
305
328
306
#pragma mark -
329
307
#pragma mark Memory management
330
308
331
- - (void )viewDidUnload
309
+ - (void )didReceiveMemoryWarning
332
310
{
333
311
[self stopScanning ];
334
-
312
+
335
313
self.prevLayer = nil ;
336
- [super viewDidUnload ];
314
+ [super didReceiveMemoryWarning ];
337
315
}
338
316
339
317
- (void )dealloc {
@@ -366,7 +344,7 @@ - (void) deinitCapture {
366
344
#if USE_MWOVERLAY
367
345
[MWOverlay removeFromPreviewLayer ];
368
346
#endif
369
-
347
+
370
348
#if !__has_feature(objc_arc)
371
349
[self .captureSession release ];
372
350
#endif
@@ -378,28 +356,22 @@ - (void) deinitCapture {
378
356
379
357
380
358
- (void )decodeResultNotification : (NSNotification *)notification {
381
-
359
+
382
360
if ([notification.object isKindOfClass: [DecoderResult class ]]) {
383
361
DecoderResult *obj = (DecoderResult*)notification.object ;
384
362
if (obj.succeeded ) {
385
363
decodeResult = [[NSString alloc ] initWithString: obj.result];
386
-
364
+
387
365
// Call the delegate to return the decodeResult and dismiss the camera view
388
366
[self .delegate returnScanResult: self scanResult: decodeResult];
389
367
[self dismissViewControllerAnimated: YES completion: nil ];
390
368
}
391
369
}
392
370
}
393
371
394
- - (void )alertView : (UIAlertView *)alertView didDismissWithButtonIndex : (NSInteger )buttonIndex {
395
- if (buttonIndex == 0 ) {
396
- [self startScanning ];
397
- }
398
- }
372
+ - (enum UIInterfaceOrientationMask)supportedInterfaceOrientations {
373
+ UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication ] statusBarOrientation ];
399
374
400
- - (NSUInteger )supportedInterfaceOrientations {
401
- UIInterfaceOrientation interfaceOrientation =[[UIApplication sharedApplication ] statusBarOrientation ];
402
-
403
375
switch (interfaceOrientation) {
404
376
case UIInterfaceOrientationPortrait:
405
377
return UIInterfaceOrientationMaskPortrait;
@@ -416,18 +388,14 @@ - (NSUInteger)supportedInterfaceOrientations {
416
388
default :
417
389
break ;
418
390
}
419
-
391
+
420
392
return UIInterfaceOrientationMaskAll;
421
393
}
422
394
423
395
- (BOOL ) shouldAutorotate {
424
396
return YES ;
425
397
}
426
398
427
- - (BOOL )shouldAutorotateToInterfaceOrientation : (UIInterfaceOrientation)interfaceOrientation {
428
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
429
- }
430
-
431
399
- (void )touchesEnded : (NSSet *)touches withEvent : (UIEvent *)event {
432
400
[self toggleTorch ];
433
401
}
0 commit comments