├── .gitignore ├── README.md ├── SESmartID ├── SESIDCameraManager.h ├── SESIDCameraManager.m ├── SESIDQuadrangleView.h ├── SESIDQuadrangleView.mm ├── SESIDRecognitionCore.h ├── SESIDRecognitionCore.mm ├── SESIDRoiOverlayView.h ├── SESIDRoiOverlayView.m ├── SESIDViewController.h └── SESIDViewController.mm ├── SESmartIDCore ├── data-zip │ └── bundle_mock_smart_idreader.zip ├── include │ └── smartIdEngine │ │ ├── smartid_common.h │ │ ├── smartid_engine.h │ │ └── smartid_result.h └── lib │ └── libsmartid-universal.a ├── SESmartIDSample.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── SESmartIDSample ├── Default-568h@2x.png ├── Info.plist ├── SESIDSampleAppDelegate.h ├── SESIDSampleAppDelegate.m ├── SESIDSampleViewController.h ├── SESIDSampleViewController.mm └── main.m └── doc ├── DocumentsReference.html ├── DocumentsReference.md ├── README.md ├── SmartIDReaderSDK.html ├── SmartIDReaderSDK.md ├── iOSIntegrationGuide.html ├── iOSIntegrationGuide.md └── smartIdEngine.pdf /.gitignore: -------------------------------------------------------------------------------- 1 | xcuserdata/ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Smart IDReader iOS SDK - Demo version 2 | 3 | This is a **DEMO** version of [Smart IDReader](https://smartengines.com/smart-id-reader/) iOS SDK by [Smart Engines](https://smartengines.com) which demonstrates the usage of Smart IDReader library/SDK without actually providing any recognition functionality. 4 | Instead, it outputs fake results for document search, field segmentation, recognition and photo image extraction. 5 | 6 | Simply open `SESmartIDSample.xcodeproj` and run it to see the working example. 7 | You are free to change the code however you want. 8 | 9 | More documentation is available in [doc](doc) directory. 10 | 11 | Free demonstrational applications with full functionality are available at [App Store](https://itunes.apple.com/app/smart-idreader/id1157877082) and [Google Play](https://play.google.com/store/apps/details?id=biz.smartengines.smartid). 12 | 13 | If you'd like to obtain a trial or full version of Smart IDReader please contact us via: 14 | * support@smartengines.com 15 | * https://smartengines.com/contacts 16 | * https://smartengines.ru/contacts 17 | 18 | Test and trial/full versions are only different in static library + configuration files so you wouldn't have to rewrite any code after you're finished integrating Smart IDReader SDK into your application. 19 | 20 | ## Smart IDReader overview 21 | 22 | Smart IDReader technology allows you to recognize identity and property rights documents while using video/photo cameras and scanners in mobile, desktop, server and terminal solutions. With this tecnhology you only need to present the document to the camera to let Smart IDReader recognize all required data in 1-3 seconds and then fill them in any file, form or a work sheet. 23 | 24 | Key features: 25 | * Real time document recognition in video stream on mobile devices 26 | * Recognition of documents in various lighting conditions 27 | * White label license 28 | * Security: only device RAM is used, no personal data is being copied or sent over the internet (e.g. for processing on servers) 29 | 30 | Supported platforms: iOS, Android, Windows, Linux, MacOS, Solaris and othaers 31 | Supported programming languages: C++, C, C#, Objective-C, Java, Visual Basic and others 32 | Supported architectures: armv7-v8, aarch64, x86, x86_64, SPARC, E2K and others 33 | 34 | ## Smart IDReader SDK Integration Guide for iOS 35 | 36 | ### 1. Configuring Xcode project 37 | 38 | 1. Add `SESmartID` folder containing Objective-C source files to your project, select **Create groups** in the menu 39 | 2. Add `SESmartIDCore/lib` folder containing static library to your project, select **Create groups** in the menu 40 | 3. Add `SESmartIDCore/data-zip` folder to your project, select **Create folder references** in the menu 41 | 4. Add `SESmartIDCore/include` folder to the **Header Search Paths** in project settings 42 | 43 | ### 2. Sample code tutorial 44 | 45 | 1. Make your ViewController (```SESIDSampleViewController``` in sample project) conform to `````` and add an instance of ```SESIDViewController``` (for example, as a property). Note, that every `.m` file that includes `SESIDViewController.h` should be renamed to `.mm` to enable Objective-C++ compilation for this file. 46 | 47 | ```objectivec 48 | // SESIDSampleViewController.h 49 | 50 | #import "SESIDViewController.h" 51 | 52 | @interface SESIDSampleViewController : UIViewController 53 | 54 | @property (nonatomic, strong) SESIDViewController *smartIdViewController; 55 | 56 | // ... 57 | @end 58 | ``` 59 | 60 | Another way is to use *anonymous category* inside implementation file 61 | (details: [Apple Developer website](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW3)). The advantage is that you'll need to rename only one file's extension to `.mm` 62 | 63 | ```objectivec++ 64 | // SESIDSampleViewController.h 65 | 66 | // left unchanged 67 | @interface SESIDSampleViewController : UIViewController 68 | // ... 69 | @end 70 | 71 | // SESIDSampleViewController.mm 72 | 73 | #import "SESIDViewController.h" 74 | 75 | @interface SESIDSampleViewController () 76 | 77 | @property SESIDViewController *smartIdViewController; 78 | 79 | @end 80 | ``` 81 | 82 | 2. Create and configure ```SESIDViewController``` instance 83 | 84 | ```objectivec++ 85 | // SESIDSampleViewController.mm 86 | 87 | // this might be called from viewDidLoad or similar methods, 88 | // depends on when do you want recognition core to be initialized. 89 | // could be done in the background thread 90 | - (void) initializeSmartIdViewController { 91 | // core configuration may take a while so it's better to be done 92 | // before displaying smart id view controller 93 | self.smartIdViewController = [[SESIDViewController alloc] init]; 94 | 95 | // assigning self as delegate to get smartIdViewControlerDidRecognizeResult called 96 | self.smartIdViewController.delegate = self; 97 | 98 | // configure optional visualization properties (they are NO by default) 99 | self.smartIdViewController.displayDocumentQuadrangle = YES; 100 | } 101 | ``` 102 | 103 | 3. Implement ```smartIdViewControllerDidRecognizeResult:``` method which will be called when ```SESIDViewController``` has successfully scanned a document and ```smartIdViewControllerDidCancel``` method which will be called when recognition has been cancelled by user 104 | 105 | ```objectivec++ 106 | // SESIDSampleViewController.mm 107 | 108 | - (void) smartIdViewControllerDidRecognizeResult:(const se::smartid::RecognitionResult &)result { 109 | // if result is not terminal we'd probably want to continue recognition until it becomes terminal 110 | // you can also check individual fields using result.GetStringField("field_name").IsAccepted() 111 | // in order to conditionally stop recognition when required fields are accepted 112 | if (!result.IsTerminal()) { 113 | return; 114 | } 115 | 116 | // dismiss Smart ID OCR view controller 117 | [self dismissViewControllerAnimated:YES completion:nil]; 118 | 119 | // use recognition result, see sample code for details 120 | // ... 121 | } 122 | 123 | - (void) smartIdViewControllerDidCancel { 124 | // dismiss Smart ID OCR view controller 125 | [self dismissViewControllerAnimated:YES completion:nil]; 126 | 127 | // ... 128 | } 129 | 130 | 131 | ``` 132 | 133 | 4. Present ```SESIDViewController``` modally when needed, set enabled document types before presenting 134 | 135 | ```objectivec++ 136 | // SESIDSampleViewController.mm 137 | 138 | - (void) showSmartIdViewController { 139 | if (!self.smartIdViewController) { 140 | [self initializeSmartIdViewController]; 141 | } 142 | 143 | // important! 144 | // setting enabled document types for this view controller 145 | // according to available document types for your delivery 146 | // these types will be passed to se::smartid::SessionSettings 147 | // with which se::smartid::RecognitionEngine::SpawnSession(...) is called 148 | // internally when Smart ID view controller is presented 149 | // you can specify a concrete document type or a wildcard expression (for convenience) 150 | // to enable or disable multiple types 151 | // by default no document types are enabled 152 | // if exception is thrown please read the exception message 153 | // see self.smartidViewController.supportedDocumentTypes, 154 | // se::smartid::SessionSettings and Smart IDReader documentation for further information 155 | [self.smartIdViewController removeEnabledDocumentTypesMask:"*"]; 156 | 157 | // [self.smartIdViewController addEnabledDocumentTypesMask:"*"]; 158 | [self.smartIdViewController addEnabledDocumentTypesMask:"mrz.*"]; 159 | // [self.smartIdViewController addEnabledDocumentTypesMask:"card.*"]; 160 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.passport.*"]; 161 | // [self.smartIdViewController addEnabledDocumentTypesMask:"deu.id.*"]; 162 | // [self.smartIdViewController addEnabledDocumentTypesMask:"gbr.drvlic.*"]; 163 | // ... 164 | 165 | // if needed, set a timeout in seconds 166 | self.smartIdViewController.sessionTimeout = 5.0f; 167 | 168 | // presenting OCR view controller 169 | [self presentViewController:self.smartIdViewController 170 | animated:YES 171 | completion:nil]; 172 | 173 | // if you want to deinitialize view controller to save the memory, do this: 174 | // self.smartIdViewController = nil; 175 | } 176 | ``` 177 | -------------------------------------------------------------------------------- /SESmartID/SESIDCameraManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | #import 32 | 33 | @interface SESIDCameraManager : NSObject 34 | 35 | - (id) init; 36 | 37 | - (void) setSampleBufferDelegate:(id)delegate; 38 | 39 | - (void) startCaptureSession; 40 | - (void) stopCaptureSession; 41 | 42 | - (AVCaptureVideoPreviewLayer *) addPreviewLayerToView:(UIView *)view 43 | orientation:(AVCaptureVideoOrientation)orientation; 44 | 45 | - (CGSize) videoSize; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /SESmartID/SESIDCameraManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDCameraManager.h" 30 | 31 | @interface SESIDCameraManager() 32 | 33 | @property (nonatomic) AVCaptureDevice *captureDevice; 34 | @property (nonatomic) AVCaptureDeviceInput *captureDeviceInput; 35 | @property (nonatomic) AVCaptureVideoDataOutput *captureVideoDataOutput; 36 | 37 | @property (nonatomic) AVCaptureSession *captureSession; 38 | 39 | @end 40 | 41 | @implementation SESIDCameraManager 42 | 43 | - (id) init { 44 | if (self = [super init]) { 45 | [self initVideoCapture]; 46 | } 47 | return self; 48 | } 49 | 50 | - (void) initVideoCapture { 51 | // capture device 52 | self.captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 53 | 54 | // setting continuous auto focus 55 | if ([self.captureDevice lockForConfiguration:nil]) { 56 | if ([self.captureDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) { 57 | self.captureDevice.focusMode = AVCaptureFocusModeContinuousAutoFocus; 58 | } 59 | [self.captureDevice unlockForConfiguration]; 60 | } 61 | 62 | // capture video data output 63 | self.captureVideoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; 64 | self.captureVideoDataOutput.videoSettings = @{(NSString*)kCVPixelBufferPixelFormatTypeKey: 65 | @(kCVPixelFormatType_32BGRA)}; 66 | self.captureVideoDataOutput.alwaysDiscardsLateVideoFrames = YES; 67 | 68 | // capture device input 69 | self.captureDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice 70 | error:nil]; 71 | 72 | // capture session 73 | self.captureSession = [[AVCaptureSession alloc] init]; 74 | self.captureSession.sessionPreset = AVCaptureSessionPreset1280x720; 75 | 76 | if([self.captureSession canAddInput:self.captureDeviceInput]) { 77 | [self.captureSession addInput:self.captureDeviceInput]; 78 | } 79 | 80 | [self.captureSession addOutput:self.captureVideoDataOutput]; 81 | } 82 | 83 | - (void) startCaptureSession { 84 | [self.captureSession startRunning]; 85 | } 86 | 87 | - (void) stopCaptureSession { 88 | [self.captureSession stopRunning]; 89 | } 90 | 91 | - (AVCaptureVideoPreviewLayer *) addPreviewLayerToView:(UIView *)view 92 | orientation:(AVCaptureVideoOrientation)orientation { 93 | CALayer *viewLayer = view.layer; 94 | 95 | AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [AVCaptureVideoPreviewLayer 96 | layerWithSession:self.captureSession]; 97 | 98 | captureVideoPreviewLayer.frame = viewLayer.bounds; 99 | captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspect; 100 | captureVideoPreviewLayer.position = CGPointMake(CGRectGetMidX(viewLayer.bounds), 101 | CGRectGetMidY(viewLayer.bounds)); 102 | captureVideoPreviewLayer.connection.videoOrientation = orientation; 103 | 104 | [viewLayer insertSublayer:captureVideoPreviewLayer atIndex:0]; 105 | 106 | return captureVideoPreviewLayer; 107 | } 108 | 109 | - (void) setSampleBufferDelegate:(id)delegate { 110 | dispatch_queue_t videoQueue = dispatch_queue_create("biz.smartengines.video-queue", 0); 111 | [self.captureVideoDataOutput setSampleBufferDelegate:delegate 112 | queue:videoQueue]; 113 | } 114 | 115 | - (CGSize) videoSize { 116 | return CGSizeMake(1280, 720); 117 | } 118 | 119 | @end 120 | -------------------------------------------------------------------------------- /SESmartID/SESIDQuadrangleView.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | #include 32 | 33 | @interface SESIDQuadrangleView : UIView 34 | 35 | @property (nonatomic, assign) CGSize drawingScale; 36 | 37 | - (id) init; 38 | 39 | - (void) animateQuadrangle:(const se::smartid::Quadrangle &)quadrangle 40 | color:(UIColor *)color 41 | width:(CGFloat)width 42 | alpha:(CGFloat)alpha; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /SESmartID/SESIDQuadrangleView.mm: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDQuadrangleView.h" 30 | 31 | @interface SESIDQuadrangleView() 32 | 33 | @end 34 | 35 | @implementation SESIDQuadrangleView 36 | 37 | - (id) init { 38 | if (self = [super init]) { 39 | [self setBackgroundColor:[UIColor clearColor]]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void) animateQuadrangle:(const se::smartid::Quadrangle &)quadrangle 45 | color:(UIColor *)color 46 | width:(CGFloat)width 47 | alpha:(CGFloat)alpha { 48 | CAShapeLayer *layer = [CAShapeLayer layer]; 49 | layer.path = [self bezierPathForQuadrangle:quadrangle].CGPath; 50 | layer.backgroundColor = UIColor.redColor.CGColor; 51 | layer.strokeColor = color.CGColor; 52 | layer.fillColor = [UIColor clearColor].CGColor; 53 | layer.lineWidth = width; 54 | layer.opacity = 0.0f; 55 | 56 | [self.layer addSublayer:layer]; 57 | 58 | __weak CAShapeLayer *weakLayer = layer; 59 | 60 | dispatch_async(dispatch_get_main_queue(), ^{ 61 | [CATransaction begin]; 62 | [CATransaction setCompletionBlock:^{ 63 | dispatch_async(dispatch_get_main_queue(), ^{ 64 | [weakLayer removeFromSuperlayer]; 65 | }); 66 | }]; 67 | 68 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 69 | animation.fromValue = @(alpha); 70 | animation.toValue = @(0.0f); 71 | animation.duration = 0.7f; 72 | 73 | [weakLayer addAnimation:animation forKey:animation.keyPath]; 74 | 75 | [CATransaction commit]; 76 | [self setNeedsDisplay]; 77 | }); 78 | } 79 | 80 | - (UIBezierPath *) bezierPathForQuadrangle:(const se::smartid::Quadrangle &)smartIdQuadrangle { 81 | UIBezierPath *path = [UIBezierPath bezierPath]; 82 | const se::smartid::Point first = [self scaledPoint:smartIdQuadrangle[0]]; 83 | [path moveToPoint:CGPointMake(first.x, first.y)]; 84 | 85 | for (int i = 0; i < 4; ++i) { 86 | const se::smartid::Point next = [self scaledPoint:smartIdQuadrangle[(i + 1) % 4]]; 87 | [path addLineToPoint:CGPointMake(next.x, next.y)]; 88 | } 89 | return path; 90 | } 91 | 92 | - (se::smartid::Point) scaledPoint:(const se::smartid::Point &)point { 93 | se::smartid::Point scaled(point.x * self.drawingScale.width, point.y * self.drawingScale.height); 94 | return scaled; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /SESmartID/SESIDRecognitionCore.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | #include 32 | 33 | @interface SESIDRecognitionCore : NSObject 34 | 35 | @property (atomic, assign) BOOL canProcessFrames; 36 | 37 | - (id) init; 38 | 39 | - (se::smartid::SessionSettings &) sessionSettings; 40 | 41 | - (void) initializeSessionWithReporter:(se::smartid::ResultReporterInterface *)resultReporter; 42 | 43 | - (se::smartid::RecognitionResult) processSampleBuffer:(CMSampleBufferRef)sampleBuffer 44 | orientation:(se::smartid::ImageOrientation)orientation; 45 | 46 | - (se::smartid::RecognitionResult) processUncompressedImageData:(uint8_t *)imageData 47 | width:(int)width 48 | height:(int)height 49 | stride:(int)stride 50 | channels:(int)channels 51 | orientation:(se::smartid::ImageOrientation)orientation; 52 | 53 | + (UIImage *) uiImageFromSmartIdImage:(const se::smartid::Image &)image; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /SESmartID/SESIDRecognitionCore.mm: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDRecognitionCore.h" 30 | 31 | #import 32 | 33 | #include 34 | 35 | @interface SESIDRecognitionCore() { 36 | std::unique_ptr sessionSettings_; 37 | std::unique_ptr engine_; 38 | std::unique_ptr session_; 39 | } 40 | 41 | @end 42 | 43 | @implementation SESIDRecognitionCore 44 | 45 | - (id) init { 46 | if (self = [super init]) { 47 | self.canProcessFrames = NO; 48 | 49 | [self initRecognitionCore]; 50 | } 51 | return self; 52 | } 53 | 54 | - (void) initRecognitionCore { 55 | NSString *dataPath = [self pathForSingleDataArchive]; 56 | 57 | try { 58 | // creating recognition engine 59 | engine_.reset(new se::smartid::RecognitionEngine(dataPath.UTF8String)); 60 | 61 | // creating default session settings 62 | sessionSettings_.reset(engine_->CreateSessionSettings()); 63 | 64 | const std::vector > &supportedDocumentTypes = 65 | sessionSettings_->GetSupportedDocumentTypes(); 66 | NSLog(@"Supported document types for configured engine:"); 67 | for (size_t i = 0; i < supportedDocumentTypes.size(); ++i) { 68 | const std::vector &supportedGroup = supportedDocumentTypes[i]; 69 | NSMutableString *supportedGroupString = [NSMutableString string]; 70 | for (size_t j = 0; j < supportedGroup.size(); ++j) { 71 | [supportedGroupString appendFormat:@"%s", supportedGroup[j].c_str()]; 72 | if (j + 1 != supportedGroup.size()) { 73 | [supportedGroupString appendString:@", "]; 74 | } 75 | } 76 | NSLog(@"[%zu]: [%@]", i, supportedGroupString); 77 | } 78 | } 79 | catch (const std::exception &e) { 80 | [NSException raise:@"SmartIDException" 81 | format:@"Exception thrown during initialization: %s", e.what()]; 82 | } 83 | } 84 | 85 | - (void) initializeSessionWithReporter:(se::smartid::ResultReporterInterface *)resultReporter { 86 | try { 87 | const std::vector &documentTypes = sessionSettings_->GetEnabledDocumentTypes(); 88 | NSLog(@"Enabled document types for recognition session to be created:"); 89 | for (size_t i = 0; i < documentTypes.size(); ++i) { 90 | NSLog(@"%s", documentTypes[i].c_str()); 91 | } 92 | 93 | // creating recognition session 94 | session_.reset(engine_->SpawnSession(*sessionSettings_, resultReporter)); 95 | } catch (const std::exception &e) { 96 | [NSException raise:@"SmartIDException" 97 | format:@"Exception thrown during session spawn: %s", e.what()]; 98 | } 99 | 100 | self.canProcessFrames = YES; 101 | } 102 | 103 | - (se::smartid::SessionSettings &) sessionSettings { 104 | return *sessionSettings_; 105 | } 106 | 107 | - (se::smartid::RecognitionResult) processSampleBuffer:(CMSampleBufferRef)sampleBuffer 108 | orientation:(se::smartid::ImageOrientation)orientation { 109 | // extracting image data from sample buffer 110 | CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); 111 | 112 | CVPixelBufferLockBaseAddress(imageBuffer, 0); 113 | uint8_t *basePtr = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 114 | 115 | const size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 116 | const size_t width = CVPixelBufferGetWidth(imageBuffer); 117 | const size_t height = CVPixelBufferGetHeight(imageBuffer); 118 | const size_t channels = 4; // assuming BGRA 119 | 120 | if (basePtr == 0 || bytesPerRow == 0 || width == 0 || height == 0) { 121 | NSLog(@"%s - sample buffer is bad", __func__); 122 | } 123 | 124 | CVPixelBufferUnlockBaseAddress(imageBuffer, 0); 125 | 126 | // processing extracted image data 127 | return [self processUncompressedImageData:basePtr 128 | width:(int)width 129 | height:(int)height 130 | stride:(int)bytesPerRow 131 | channels:channels 132 | orientation:orientation]; 133 | } 134 | 135 | - (se::smartid::RecognitionResult) processUncompressedImageData:(uint8_t *)imageData 136 | width:(int)width 137 | height:(int)height 138 | stride:(int)stride 139 | channels:(int)channels 140 | orientation:(se::smartid::ImageOrientation)orientation { 141 | try { 142 | const size_t dataLength = stride * height; 143 | return session_->ProcessSnapshot(imageData, 144 | dataLength, 145 | width, 146 | height, 147 | stride, 148 | channels, 149 | orientation); 150 | } catch (const std::exception &e) { 151 | NSLog(@"Exception thrown during processing: %s", e.what()); 152 | } 153 | return se::smartid::RecognitionResult(); 154 | } 155 | 156 | #pragma mark - Utilities 157 | + (UIImage *) uiImageFromSmartIdImage:(const se::smartid::Image &)image { 158 | const bool shouldCopy = true; 159 | 160 | NSData *data = nil; 161 | if (shouldCopy) { 162 | data = [NSData dataWithBytes:image.data 163 | length:image.height * image.stride]; 164 | } else { 165 | data = [NSData dataWithBytesNoCopy:image.data 166 | length:image.height * image.stride 167 | freeWhenDone:NO]; 168 | } 169 | 170 | CGColorSpaceRef colorSpace; 171 | if (image.channels == 1) { 172 | colorSpace = CGColorSpaceCreateDeviceGray(); 173 | } else { 174 | colorSpace = CGColorSpaceCreateDeviceRGB(); 175 | } 176 | 177 | CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); 178 | 179 | CGImageRef imageRef = CGImageCreate(image.width, // Width 180 | image.height, // Height 181 | 8, // Bits per component 182 | 8 * image.channels, // Bits per pixel 183 | image.stride, // Bytes per row 184 | colorSpace, // Colorspace 185 | kCGImageAlphaNone | kCGBitmapByteOrderDefault, // Bitmap info flags 186 | provider, // CGDataProviderRef 187 | NULL, // Decode 188 | false, // Should interpolate 189 | kCGRenderingIntentDefault); // Intent 190 | 191 | UIImage *ret = [UIImage imageWithCGImage:imageRef 192 | scale:1.0f 193 | orientation:UIImageOrientationUp]; 194 | 195 | CGImageRelease(imageRef); 196 | CGDataProviderRelease(provider); 197 | CGColorSpaceRelease(colorSpace); 198 | 199 | return ret; 200 | } 201 | 202 | - (NSString *) pathForSingleDataArchive { 203 | NSBundle *bundle = [NSBundle bundleForClass:[self classForCoder]]; 204 | NSString *dataPath = [bundle pathForResource:@"data-zip" ofType:nil]; 205 | NSArray *listdir = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dataPath error:nil]; 206 | NSPredicate *zipFilter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.zip'"]; 207 | NSArray *zipArchives = [listdir filteredArrayUsingPredicate:zipFilter]; 208 | NSAssert(zipArchives.count == 1, @"data-zip folder must contain single .zip archive"); 209 | NSString *zipName = [zipArchives objectAtIndex:0]; 210 | NSString *zipPath = [dataPath stringByAppendingPathComponent:zipName]; 211 | return zipPath; 212 | } 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /SESmartID/SESIDRoiOverlayView.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | @interface SESIDRoiOverlayView : UIView 32 | 33 | @property (nonatomic, assign, setter=setWidthAspectRatio:) CGFloat widthAspectRatio; 34 | 35 | @property (nonatomic, readonly) CGRect roiRect; 36 | 37 | @property (nonatomic, assign) CGFloat glowColorLevel; 38 | 39 | - (id) init; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /SESmartID/SESIDRoiOverlayView.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDRoiOverlayView.h" 30 | 31 | #import 32 | 33 | @interface SESIDRoiOverlayView() 34 | 35 | @property (nonatomic, assign) CGRect roiRect; 36 | 37 | @end 38 | 39 | @implementation SESIDRoiOverlayView 40 | 41 | - (id) init { 42 | if (self = [super init]) { 43 | self.widthAspectRatio = 0.0f; 44 | 45 | self.backgroundColor = [UIColor clearColor]; 46 | 47 | self.glowColorLevel = 0.0f; 48 | } 49 | return self; 50 | } 51 | 52 | - (void) drawRect:(CGRect)rect { 53 | if (self.widthAspectRatio == 0.0f) { 54 | return; 55 | } 56 | 57 | CGContextRef context = UIGraphicsGetCurrentContext(); 58 | 59 | // assuming self.bounds already have video frames aspect ratio (e.g. 16:9) 60 | CGRect viewRect = self.bounds; 61 | 62 | CGContextAddRect(context, viewRect); 63 | CGContextAddRect(context, self.roiRect); 64 | CGContextSetGrayFillColor(context, 0.5f, 0.66f); 65 | CGContextEOFillPath(context); 66 | 67 | if (self.glowColorLevel >= 0.0f) { 68 | const CGRect topRect = CGRectMake(viewRect.origin.x, 69 | viewRect.origin.y, 70 | viewRect.size.width, 71 | self.roiRect.origin.y - viewRect.origin.y); 72 | [self drawGradientInContext:context rect:topRect start:0.0f end:1.0f]; 73 | 74 | const CGRect bottomRect = CGRectMake(viewRect.origin.x, 75 | self.roiRect.origin.y + self.roiRect.size.height, 76 | viewRect.size.width, 77 | topRect.size.height); 78 | [self drawGradientInContext:context rect:bottomRect start:1.0f end:0.0f]; 79 | } 80 | } 81 | 82 | - (void) drawGradientInContext:(CGContextRef)context rect:(CGRect)rect 83 | start:(CGFloat)start end:(CGFloat)end { 84 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 85 | CGFloat locations[] = { start, end }; 86 | 87 | NSArray *colors = @[(__bridge id)[UIColor clearColor].CGColor, 88 | (__bridge id)[self glowColor].CGColor]; 89 | 90 | CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, 91 | (__bridge CFArrayRef) colors, 92 | locations); 93 | 94 | CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect)); 95 | CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect)); 96 | 97 | CGContextSaveGState(context); 98 | CGContextAddRect(context, rect); 99 | CGContextClip(context); 100 | CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); 101 | CGContextRestoreGState(context); 102 | 103 | CGGradientRelease(gradient); 104 | CGColorSpaceRelease(colorSpace); 105 | } 106 | 107 | - (void) setWidthAspectRatio:(CGFloat)widthAspectRatio { 108 | _widthAspectRatio = widthAspectRatio; 109 | 110 | [self updateRoiRect]; 111 | } 112 | 113 | - (void) updateRoiRect { 114 | const CGFloat roiHeight = self.bounds.size.width / self.widthAspectRatio; 115 | 116 | self.roiRect = CGRectMake(0, 117 | self.bounds.size.height / 2 - roiHeight / 2, 118 | self.bounds.size.width, 119 | roiHeight); 120 | [self setNeedsDisplay]; 121 | } 122 | 123 | - (void) layoutSubviews { 124 | [super layoutSubviews]; 125 | 126 | [self updateRoiRect]; 127 | } 128 | 129 | - (UIColor *) glowColor { 130 | self.glowColorLevel = MIN(1.0f, MAX(0.0f, self.glowColorLevel)); 131 | return [UIColor colorWithRed:0.7f * (1.0f - self.glowColorLevel) 132 | green:0.7f 133 | blue:0.0f 134 | alpha:0.5f * self.glowColorLevel]; 135 | } 136 | 137 | @end 138 | // 139 | -------------------------------------------------------------------------------- /SESmartID/SESIDViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | #include 32 | 33 | /***************************************************************************** 34 | SESIDViewController is a convenience Objective-C++ wrapper class 35 | for Smart ID C++ recognition library by Smart Engines. 36 | 37 | Please see Smart ID documentation for details and C++ classes usage. 38 | 39 | Feel free to modify the source code to meet your needs or contact Smart Engines. 40 | *****************************************************************************/ 41 | 42 | 43 | @protocol SESIDViewControllerDelegate 44 | 45 | - (void) smartIdViewControllerDidRecognizeResult:(const se::smartid::RecognitionResult &)smartIdResult; 46 | 47 | - (void) smartIdViewControllerDidCancel; 48 | 49 | @end 50 | 51 | 52 | @interface SESIDViewController : UIViewController 53 | 54 | @property (weak) id delegate; // receives recognition callbacks 55 | 56 | @property (nonatomic, assign) BOOL displayDocumentQuadrangle; // NO by default 57 | @property (nonatomic, assign) BOOL displayZonesQuadrangles; // NO by default 58 | 59 | @property (nonatomic) float sessionTimeout; // sets result to terminal after timeout, 0 means no timeout 60 | 61 | @property (nonatomic) UIButton *cancelButton; // cancels scanning, user is able to modify it 62 | 63 | - (id) init; 64 | 65 | // getter for mutable recognition session settings reference, change them if needed 66 | - (se::smartid::SessionSettings &) sessionSettings; 67 | 68 | // important methods for enabling document types for recognition session 69 | // wildcard expressions can be used 70 | // by default no document types are enabled 71 | // see se::smartid::SessionSettings for details 72 | - (void) addEnabledDocumentTypesMask:(const std::string &)documentTypesMask; 73 | - (void) removeEnabledDocumentTypesMask:(const std::string &)documentTypesMask; 74 | 75 | // actual document types without wildcard expressions 76 | - (void) setEnabledDocumentTypes:(const std::vector &)documentTypes; 77 | - (const std::vector &) enabledDocumentTypes; 78 | 79 | // list of supported document groups that can be enabled together 80 | - (const std::vector > &) supportedDocumentTypes; 81 | 82 | // convert se::smartid::Image to UIImage e.g. for display purposes 83 | + (UIImage *) uiImageFromSmartIdImage:(const se::smartid::Image &)image; 84 | 85 | @end 86 | -------------------------------------------------------------------------------- /SESmartID/SESIDViewController.mm: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDViewController.h" 30 | 31 | #import "SESIDCameraManager.h" 32 | #import "SESIDRecognitionCore.h" 33 | 34 | #import "SESIDRoiOverlayView.h" 35 | #import "SESIDQuadrangleView.h" 36 | 37 | // SmartIDResultReporter 38 | struct SmartIDResultReporter : public se::smartid::ResultReporterInterface { 39 | __weak SESIDViewController *smartIdViewController; // to pass data back to view controller 40 | 41 | int processedFramesCount; 42 | 43 | virtual void SnapshotRejected() override; 44 | virtual void DocumentMatched( 45 | const std::vector& match_results) override; 46 | virtual void DocumentSegmented( 47 | const std::vector& segmentation_results) override; 48 | virtual void SnapshotProcessed(const se::smartid::RecognitionResult& recog_result) override; 49 | virtual void SessionEnded() override; 50 | virtual ~SmartIDResultReporter(); 51 | }; 52 | 53 | // SESIDViewController 54 | @interface SESIDViewController () { 55 | SmartIDResultReporter resultReporter_; 56 | } 57 | 58 | @property (nonatomic) SESIDCameraManager *cameraManager; 59 | @property (nonatomic) SESIDRecognitionCore *recognitionCore; 60 | 61 | @property (nonatomic) AVCaptureVideoPreviewLayer *previewLayer; 62 | @property (nonatomic) SESIDRoiOverlayView *roiOverlayView; 63 | @property (nonatomic) SESIDQuadrangleView *quadrangleView; 64 | @property (nonatomic) UIImageView *logoImageView; 65 | 66 | @property (nonatomic, assign) BOOL guiInitialized; 67 | 68 | @end 69 | 70 | @implementation SESIDViewController 71 | 72 | #pragma mark - Initialization and life cycle 73 | - (id) init { 74 | if (self = [super init]) { 75 | [self initCameraManager]; 76 | [self initRecognitionCore]; 77 | [self initRoiOverlayView]; 78 | [self initQuadrangleView]; 79 | [self initLogoImageView]; 80 | [self initCancelButton]; 81 | 82 | self.view.backgroundColor = [UIColor blackColor]; 83 | 84 | self.displayDocumentQuadrangle = NO; 85 | self.displayZonesQuadrangles = NO; 86 | } 87 | 88 | return self; 89 | } 90 | 91 | - (void) initCameraManager { 92 | self.cameraManager = [[SESIDCameraManager alloc] init]; 93 | 94 | __weak typeof(self) weakSelf = self; 95 | [self.cameraManager setSampleBufferDelegate:weakSelf]; 96 | } 97 | 98 | - (void) initRecognitionCore { 99 | self.recognitionCore = [[SESIDRecognitionCore alloc] init]; 100 | 101 | __weak typeof(self) weakSelf = self; 102 | resultReporter_.smartIdViewController = weakSelf; 103 | } 104 | 105 | - (void) initRoiOverlayView { 106 | self.roiOverlayView = [[SESIDRoiOverlayView alloc] init]; 107 | [self.view addSubview:self.roiOverlayView]; 108 | } 109 | 110 | - (void) initQuadrangleView { 111 | self.quadrangleView = [[SESIDQuadrangleView alloc] init]; 112 | [self.view addSubview:self.quadrangleView]; 113 | } 114 | 115 | - (void) initLogoImageView { 116 | UIImage *logoImage = [UIImage imageNamed:@""]; 117 | 118 | CGRect frame = CGRectMake(10, 10, 60, 60); 119 | self.logoImageView = [[UIImageView alloc] initWithFrame:frame]; 120 | self.logoImageView.image = logoImage; 121 | } 122 | 123 | - (void) initCancelButton { 124 | self.cancelButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 125 | [self.cancelButton addTarget:self action:@selector(cancelButtonPressed) 126 | forControlEvents:UIControlEventTouchUpInside]; 127 | [self.cancelButton setTitle:@"X" forState:UIControlStateNormal]; 128 | [self.cancelButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 129 | [self.cancelButton.titleLabel setFont:[UIFont boldSystemFontOfSize:30.0f]]; 130 | [self.view addSubview:self.cancelButton]; 131 | [self.view bringSubviewToFront:self.cancelButton]; 132 | } 133 | 134 | - (void) viewDidLayoutSubviews { 135 | // calculating roi overlay view to aspect fill camera view 136 | 137 | CGSize videoSize = self.cameraManager.videoSize; 138 | CGRect bounds = self.view.bounds; 139 | CGRect frame = bounds; 140 | 141 | if (!UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) { 142 | videoSize = CGSizeMake(videoSize.height, videoSize.width); 143 | 144 | const CGFloat height = frame.size.width * (videoSize.height / videoSize.width); 145 | frame.size.height = height; 146 | frame.origin.y -= (height - frame.size.height) / 2; 147 | } else { 148 | const CGFloat width = frame.size.height * (videoSize.width / videoSize.height); 149 | frame.size.width = width; 150 | frame.origin.x -= (width - frame.size.width) / 2; 151 | } 152 | 153 | self.roiOverlayView.frame = frame; 154 | self.previewLayer.frame = self.roiOverlayView.bounds; 155 | self.quadrangleView.frame = self.roiOverlayView.frame; 156 | 157 | // calculating drawing scale for quadrangle view 158 | self.quadrangleView.drawingScale = CGSizeMake( 159 | self.quadrangleView.bounds.size.width / videoSize.width, 160 | self.quadrangleView.bounds.size.height / videoSize.height); 161 | 162 | // setting cancel button location 163 | const CGFloat cancelButtonSize = 80; 164 | self.cancelButton.frame = CGRectMake(bounds.size.width - cancelButtonSize - 10, 165 | bounds.size.height - cancelButtonSize - 10, 166 | cancelButtonSize, cancelButtonSize); 167 | } 168 | 169 | - (void) viewWillAppear:(BOOL)animated { 170 | [super viewWillAppear:animated]; 171 | 172 | self.roiOverlayView.backgroundColor = [UIColor blackColor]; 173 | 174 | self.roiOverlayView.glowColorLevel = 0.0f; 175 | 176 | [self.roiOverlayView setNeedsDisplay]; 177 | } 178 | 179 | - (void) viewDidAppear:(BOOL)animated { 180 | [super viewDidAppear:animated]; 181 | 182 | if (!self.guiInitialized) { 183 | self.previewLayer = [self.cameraManager addPreviewLayerToView:self.roiOverlayView 184 | orientation:[self currentVideoOrientation]]; 185 | 186 | [[NSNotificationCenter defaultCenter] addObserver:self 187 | selector:@selector(orientationChanged) 188 | name:UIDeviceOrientationDidChangeNotification 189 | object:nil]; 190 | [self orientationChanged]; 191 | 192 | self.guiInitialized = YES; 193 | } 194 | 195 | dispatch_async(dispatch_get_main_queue(), ^{ 196 | [self.cameraManager startCaptureSession]; 197 | self.roiOverlayView.backgroundColor = [UIColor clearColor]; 198 | }); 199 | 200 | [self.recognitionCore initializeSessionWithReporter:&resultReporter_]; 201 | } 202 | 203 | - (void) viewWillDisappear:(BOOL)animated { 204 | self.recognitionCore.canProcessFrames = NO; 205 | } 206 | 207 | - (void) viewDidDisappear:(BOOL)animated { 208 | dispatch_async(dispatch_get_main_queue(), ^{ 209 | [self.cameraManager stopCaptureSession]; 210 | }); 211 | } 212 | 213 | #pragma mark - User interaction 214 | - (void) cancelButtonPressed { 215 | self.recognitionCore.canProcessFrames = NO; 216 | 217 | [self.delegate smartIdViewControllerDidCancel]; 218 | } 219 | 220 | #pragma mark - Interface properties and other methods 221 | - (se::smartid::SessionSettings &) sessionSettings { 222 | return self.recognitionCore.sessionSettings; 223 | } 224 | 225 | - (void) setSessionTimeout:(float)sessionTimeout { 226 | NSString *str = [[NSNumber numberWithFloat:sessionTimeout] stringValue]; 227 | self.recognitionCore.sessionSettings.SetOption("common.sessionTimeout", str.UTF8String); 228 | } 229 | 230 | - (float) sessionTimeout { 231 | std::string str = self.recognitionCore.sessionSettings.GetOption("common.sessionTimeout"); 232 | float timeout = [[NSString stringWithUTF8String:str.c_str()] floatValue]; 233 | return timeout; 234 | } 235 | 236 | - (void) addEnabledDocumentTypesMask:(const std::string &)documentTypesMask { 237 | self.recognitionCore.sessionSettings.AddEnabledDocumentTypes(documentTypesMask); 238 | } 239 | 240 | - (void) removeEnabledDocumentTypesMask:(const std::string &)documentTypesMask { 241 | self.recognitionCore.sessionSettings.RemoveEnabledDocumentTypes(documentTypesMask); 242 | } 243 | 244 | - (void) setEnabledDocumentTypes:(const std::vector &)documentTypes { 245 | self.recognitionCore.sessionSettings.SetEnabledDocumentTypes(documentTypes); 246 | } 247 | 248 | - (const std::vector &) enabledDocumentTypes { 249 | return self.recognitionCore.sessionSettings.GetEnabledDocumentTypes(); 250 | } 251 | 252 | - (const std::vector > &) supportedDocumentTypes { 253 | return self.recognitionCore.sessionSettings.GetSupportedDocumentTypes(); 254 | } 255 | 256 | #pragma mark - Camera and Core interaction 257 | - (void) captureOutput:(AVCaptureOutput *)captureOutput 258 | didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 259 | fromConnection:(AVCaptureConnection *)connection { 260 | // NSLog(@"%s %d", __func__, [self.recognitionCore canProcessFrames]); 261 | 262 | if ([self.recognitionCore canProcessFrames]) { 263 | se::smartid::ImageOrientation orientation = [self currentImageOrientation]; 264 | 265 | const se::smartid::RecognitionResult result = [self.recognitionCore 266 | processSampleBuffer:sampleBuffer 267 | orientation:orientation]; 268 | 269 | // processing is performed on video queue so forcing main queue 270 | if ([NSThread isMainThread]) { 271 | [self.delegate smartIdViewControllerDidRecognizeResult:result]; 272 | } else { 273 | dispatch_sync(dispatch_get_main_queue(), ^{ 274 | [self.delegate smartIdViewControllerDidRecognizeResult:result]; 275 | }); 276 | } 277 | } 278 | } 279 | 280 | + (UIImage *) uiImageFromSmartIdImage:(const se::smartid::Image &)image { 281 | return [SESIDRecognitionCore uiImageFromSmartIdImage:image]; 282 | } 283 | 284 | - (se::smartid::ImageOrientation) currentImageOrientation { 285 | UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 286 | if (orientation == UIInterfaceOrientationPortrait) { 287 | return se::smartid::Portrait; 288 | } else if (orientation == UIInterfaceOrientationLandscapeRight) { 289 | return se::smartid::Landscape; 290 | } else if (orientation == UIInterfaceOrientationLandscapeLeft) { 291 | return se::smartid::InvertedLandscape; 292 | } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { 293 | return se::smartid::InvertedPortrait; 294 | } else { 295 | return se::smartid::Portrait; 296 | } 297 | } 298 | 299 | - (AVCaptureVideoOrientation) currentVideoOrientation { 300 | UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 301 | AVCaptureVideoOrientation videoOrientation = AVCaptureVideoOrientationPortrait; 302 | if (orientation == UIInterfaceOrientationPortrait) { 303 | videoOrientation = AVCaptureVideoOrientationPortrait; 304 | } else if (orientation == UIInterfaceOrientationLandscapeRight) { 305 | videoOrientation = AVCaptureVideoOrientationLandscapeRight; 306 | } else if (orientation == UIInterfaceOrientationLandscapeLeft) { 307 | videoOrientation = AVCaptureVideoOrientationLandscapeLeft; 308 | } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) { 309 | videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown; 310 | } 311 | return videoOrientation; 312 | } 313 | 314 | - (void) orientationChanged { 315 | AVCaptureVideoOrientation videoOrientation = [self currentVideoOrientation]; 316 | self.previewLayer.connection.videoOrientation = videoOrientation; 317 | [self viewDidLayoutSubviews]; 318 | } 319 | 320 | #pragma mark SmartIDResultReporter implementation 321 | void SmartIDResultReporter::SnapshotRejected() { 322 | // NSLog(@"%s", __FUNCTION__); 323 | } 324 | 325 | void SmartIDResultReporter::DocumentMatched( 326 | const std::vector& match_results) { 327 | // NSLog(@"%s", __FUNCTION__); 328 | 329 | if (smartIdViewController.displayDocumentQuadrangle) { 330 | for (size_t i = 0; i < match_results.size(); ++i) { 331 | dispatch_sync(dispatch_get_main_queue(), ^{ 332 | const se::smartid::MatchResult &result = match_results[i]; 333 | [smartIdViewController.quadrangleView animateQuadrangle:result.GetQuadrangle() 334 | color:UIColor.greenColor 335 | width:2.5f 336 | alpha:0.9f]; 337 | }); 338 | } 339 | } 340 | } 341 | 342 | void SmartIDResultReporter::DocumentSegmented( 343 | const std::vector& segmentation_results) { 344 | // NSLog(@"%s", __FUNCTION__); 345 | 346 | if (smartIdViewController.displayDocumentQuadrangle) { 347 | for (size_t i = 0; i < segmentation_results.size(); ++i) { 348 | const se::smartid::SegmentationResult &result = segmentation_results[i]; 349 | for (const auto &zone_quad : result.GetZoneQuadrangles()) { 350 | dispatch_sync(dispatch_get_main_queue(), ^{ 351 | [smartIdViewController.quadrangleView animateQuadrangle:zone_quad.second 352 | color:UIColor.greenColor 353 | width:1.3f 354 | alpha:0.9f]; 355 | }); 356 | } 357 | } 358 | } 359 | } 360 | 361 | void SmartIDResultReporter::SnapshotProcessed(const se::smartid::RecognitionResult &result) { 362 | // NSLog(@"%s %d", __FUNCTION__, processedFramesCount); 363 | ++processedFramesCount; 364 | } 365 | 366 | void SmartIDResultReporter::SessionEnded() { 367 | // NSLog(@"%s", __FUNCTION__); 368 | } 369 | 370 | SmartIDResultReporter::~SmartIDResultReporter() { 371 | smartIdViewController = nil; 372 | } 373 | 374 | #pragma mark - Style settings 375 | - (UIStatusBarStyle) preferredStatusBarStyle { 376 | return UIStatusBarStyleLightContent; 377 | } 378 | 379 | - (BOOL) prefersStatusBarHidden { 380 | return NO; 381 | } 382 | 383 | - (UIInterfaceOrientationMask) supportedInterfaceOrientations { 384 | return UIInterfaceOrientationMaskAll; 385 | } 386 | 387 | - (BOOL) shouldAutorotate { 388 | return YES; 389 | } 390 | 391 | @end 392 | -------------------------------------------------------------------------------- /SESmartIDCore/data-zip/bundle_mock_smart_idreader.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/90fdd5ff785b89be9f629230351f7ba906ccfbb5/SESmartIDCore/data-zip/bundle_mock_smart_idreader.zip -------------------------------------------------------------------------------- /SESmartIDCore/include/smartIdEngine/smartid_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | */ 5 | 6 | /** 7 | * @file smartid_common.h 8 | * @brief Common classes used in SmartIdEngine 9 | */ 10 | 11 | #ifndef SMARTID_ENGINE_SMARTID_COMMON_H_INCLUDED_ 12 | #define SMARTID_ENGINE_SMARTID_COMMON_H_INCLUDED_ 13 | 14 | #if defined _MSC_VER 15 | #pragma warning(push) 16 | #pragma warning(disable : 4290) 17 | #endif 18 | 19 | #if defined _WIN32 && SMARTID_ENGINE_EXPORTS 20 | #define SMARTID_DLL_EXPORT __declspec(dllexport) 21 | #else 22 | #define SMARTID_DLL_EXPORT 23 | #endif 24 | 25 | #include 26 | 27 | namespace se { namespace smartid { 28 | 29 | /** 30 | * @brief Class for representing a rectangle on an image 31 | */ 32 | class SMARTID_DLL_EXPORT Rectangle { 33 | public: 34 | /** 35 | * @brief Constructor (x = y = width = height = 0) 36 | */ 37 | Rectangle(); 38 | 39 | /** 40 | * @brief Constructor from coordinates 41 | * @param x - Top-left rectangle point x-coordinate in pixels 42 | * @param y - Top-left rectangle point y-coordinate in pixels 43 | * @param width - Rectangle width in pixels 44 | * @param height - Rectangle height in pixels 45 | */ 46 | Rectangle(int x, int y, int width, int height); 47 | 48 | public: 49 | int x; ///< x-coordinate of a top-left point in pixels 50 | int y; ///< r-coordinate of a top-left point in pixels 51 | int width; ///< rectangle width in pixels 52 | int height; ///< rectangle height in pixels 53 | }; 54 | 55 | /** 56 | * @brief Class for representing a point on an image 57 | */ 58 | class SMARTID_DLL_EXPORT Point { 59 | public: 60 | /** 61 | * @brief Default Constructor (x = y = 0) 62 | */ 63 | Point(); 64 | 65 | /** 66 | * @brief Constructor 67 | * @param x - x-coordinate of a point in pixels (top-left corner is origin) 68 | * @param y - y-coordinate of a point in pixels (top-left corner is origin) 69 | */ 70 | Point(double x, double y); 71 | 72 | double x; ///< x-coordinate in pixels (top-left corner is origin) 73 | double y; ///< y-coordinate in pixels (top-left corner is origin) 74 | }; 75 | 76 | /** 77 | * @brief Class for representing a quadrangle on an image 78 | */ 79 | class SMARTID_DLL_EXPORT Quadrangle { 80 | public: 81 | /** 82 | * @brief Constructor 83 | */ 84 | Quadrangle(); 85 | 86 | /** 87 | * @brief Constructor 88 | * @param a Top-left vertex of the quadrangle 89 | * @param b Top-right vertex of the quadrangle 90 | * @param c Bottom-right vertex of the quadrangle 91 | * @param d Bottom-left vertex of the quadrangle 92 | */ 93 | Quadrangle(Point a, Point b, Point c, Point d); 94 | 95 | /** 96 | * @brief Returns the quadrangle vertex at the given @p index as a modifiable 97 | * reference 98 | * @param index Index position for quadrangle vertex, from 0 till 3 99 | * 100 | * @throws std::out_of_range if index is not in range [0 ... 3] 101 | */ 102 | Point& operator[](int index) throw(std::exception); 103 | 104 | /** 105 | * @brief Returns the quadrangle vertex at the given @p index as a constant 106 | * reference 107 | * @param index Index position for quadrangle vertex, from 0 till 3 108 | * 109 | * @throws std::out_of_range if index is not in range [0 ... 3] 110 | */ 111 | const Point& operator[](int index) const throw(std::exception); 112 | 113 | /** 114 | * @brief Returns the quadrangle vertex at the given @p index as a constant 115 | * reference 116 | * @param index Index position for quadrangle vertex, from 0 till 3 117 | * 118 | * @throws std::out_of_range if index is not in range [0 ... 3] 119 | */ 120 | const Point& GetPoint(int index) const throw(std::exception); 121 | 122 | /** 123 | * @brief Sets the quadrangle vertex at the given @p index to specified @p 124 | * value 125 | * @param index Index position for quadrangle vertex, from 0 till 3 126 | * @param value New value for quadrangle vertex 127 | * 128 | * @throws std::out_of_range if index is not in range [0 ... 3] 129 | */ 130 | void SetPoint(int index, const Point& value) throw(std::exception); 131 | 132 | public: 133 | /// Vector of quadrangle vertices in order: 134 | /// top-left, top-right, bottom-right, bottom-left 135 | Point points[4]; 136 | }; 137 | 138 | /** 139 | * @brief Class for representing a bitmap image 140 | */ 141 | class SMARTID_DLL_EXPORT Image { 142 | public: 143 | /// Default ctor, creates null image with no memory owning 144 | Image(); 145 | 146 | /** 147 | * @brief smartid::Image ctor from image file 148 | * @param image_filename - path to an image. Supported formats: png, jpg, tif 149 | * 150 | * @throw std::runtime_error if image loading failed 151 | */ 152 | Image(const std::string& image_filename) throw(std::exception); 153 | 154 | /** 155 | * @brief smartid::Image ctor from raw buffer 156 | * @param data - pointer to a buffer start 157 | * @param data_length - length of the buffer 158 | * @param width - width of the image 159 | * @param height - height of the image 160 | * @param stride - address difference between two vertically adjacent pixels 161 | * in bytes 162 | * @param channels - number of image channels (1-grayscale, 3-RGB, 4-BGRA) 163 | * 164 | * @details resulting image is a memory-owning copy 165 | * 166 | * @throw std::runtime_error if image creating failed 167 | */ 168 | Image(unsigned char* data, size_t data_length, int width, int height, 169 | int stride, int channels) throw(std::exception); 170 | 171 | /** 172 | * @brief smartid::Image ctor from YUV buffer 173 | * @param yuv_data - Pointer to the data buffer start 174 | * @param yuv_data_length - Total length of image data buffer 175 | * @param width - Image width 176 | * @param height - Image height 177 | * 178 | * @throws std::exception if image creating failed 179 | */ 180 | Image(unsigned char* yuv_data, size_t yuv_data_length, 181 | int width, int height) throw(std::exception); 182 | 183 | /** 184 | * @brief smartid::Image copy ctor 185 | * @param copy - an image to copy from. If 'copy' doesn't own memory then only 186 | * the reference is copied. If 'copy' owns image memory then new image 187 | * will be allocated with the same data as 'copy'. 188 | */ 189 | Image(const Image& copy); 190 | 191 | /** 192 | * @brief smartid::Image assignment operator 193 | * @param other - an image to assign. If 'other' doesn't own memory then only 194 | * the reference is assigned. If 'other' owns image memory then new 195 | * image will be allocated with the same data as 'other'. 196 | */ 197 | Image& operator=(const Image& other); 198 | 199 | /// Image dtor 200 | ~Image(); 201 | 202 | /** 203 | * @brief Saves an image to file 204 | * @param image_filename - path to an image. Supported formats: png, jpg, tif, 205 | * format is deduced from the filename extension 206 | * 207 | * @throw std::runtime_error if image saving failed 208 | */ 209 | void Save(const std::string& image_filename) const throw(std::exception); 210 | 211 | /** 212 | * @brief Returns required buffer size for copying image data, O(1) 213 | * @return Buffer size in bytes 214 | */ 215 | int GetRequiredBufferLength() const; 216 | 217 | /** 218 | * @brief Copies the image data to specified buffer 219 | * @param out_buffer Destination buffer, must be preallocated 220 | * @param buffer_length Size of buffer @p out_buffer 221 | * @return Number of bytes copied 222 | * 223 | * @throw std::invalid_argument if buffer size (buffer_length) is not enough 224 | * to store the image, or if out_buffer is NULL 225 | * std::runtime_error if unexpected error happened in the copying 226 | * process 227 | */ 228 | int CopyToBuffer( 229 | char* out_buffer, int buffer_length) const throw(std::exception); 230 | 231 | /** 232 | * @brief Returns required buffer size for Base64 JPEG representation of an 233 | * image. WARNING: will perform one extra JPEG coding of an image 234 | * @return Buffer size in bytes 235 | * 236 | * @throws std::runtime_error if failed to calculate the necessary buffer size 237 | */ 238 | int GetRequiredBase64BufferLength() const throw(std::exception); 239 | 240 | /** 241 | * @brief Copy JPEG representation of the image to buffer (in base64 coding). 242 | * The buffer must be large enough. 243 | * @param out_buffer Destination buffer, must be preallocated 244 | * @param buffer_length Size of buffer @p out_buffer 245 | * @return Number of bytes copied 246 | * 247 | * @throw std::invalid_argument if buffer size (buffer_length) is not enough 248 | * to store the image, or if out_buffer is NULL. 249 | * std::runtime_error if unexpected error happened in the copying process 250 | */ 251 | int CopyBase64ToBuffer( 252 | char* out_buffer, int buffer_length) const throw(std::exception); 253 | 254 | /** 255 | * @brief Clears the internal image structure, deallocates memory if owns it 256 | */ 257 | void Clear(); 258 | 259 | /** 260 | * @brief Getter for image width 261 | * @return Image width in pixels 262 | */ 263 | int GetWidth() const; 264 | 265 | /** 266 | * @brief Getter for image height 267 | * @return Image height in pixels 268 | */ 269 | int GetHeight() const; 270 | 271 | /** 272 | * @brief Getter for number of image channels 273 | * @return Image number of channels 274 | */ 275 | int GetChannels() const; 276 | 277 | /** 278 | * @brief Returns whether this instance owns (and will release) image data 279 | * @return memown variable value 280 | */ 281 | bool IsMemoryOwner() const; 282 | 283 | /** 284 | * @brief Forces memory ownership - allocates new image data and sets 285 | * memown to true if memown was false, otherwise does nothing 286 | */ 287 | void ForceMemoryOwner(); 288 | 289 | /** 290 | * @brief Scale (resize) this image to new width and height, force memory ownership 291 | * @param new_width New image width 292 | * @param new_height New image height 293 | */ 294 | void Resize(int new_width, int new_height); 295 | 296 | public: 297 | char* data; ///< Pointer to the first pixel of the first row 298 | int width; ///< Width of the image in pixels 299 | int height; ///< Height of the image in pixels 300 | int stride; ///< Difference in bytes between addresses of adjacent rows 301 | int channels; ///< Number of image channels 302 | bool memown; ///< Whether the image owns the memory itself 303 | }; 304 | 305 | /** 306 | * @brief The ImageOrientation enum 307 | */ 308 | enum SMARTID_DLL_EXPORT ImageOrientation { 309 | Landscape, ///< image is in the proper orientation, nothing needs to be done 310 | Portrait, ///< image is in portrait, needs to be rotated 90° clockwise 311 | InvertedLandscape, ///< image is upside-down, needs to be rotated 180° 312 | InvertedPortrait ///< image is in portrait, needs to be rotated 90° 313 | ///counter-clockwise 314 | }; 315 | 316 | } } // namespace se::smartid 317 | 318 | #if defined _MSC_VER 319 | #pragma warning(pop) 320 | #endif 321 | 322 | #endif // SMARTID_ENGINE_SMARTID_COMMON_H_INCLUDED 323 | -------------------------------------------------------------------------------- /SESmartIDCore/include/smartIdEngine/smartid_engine.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012-2017, Smart Engines Ltd 3 | * All rights reserved. 4 | */ 5 | 6 | /** 7 | * @file smartid_engine.h 8 | * @brief Main processing classes 9 | */ 10 | 11 | #ifndef SMARTID_ENGINE_SMARTID_ENGINE_H_INCLUDED_ 12 | #define SMARTID_ENGINE_SMARTID_ENGINE_H_INCLUDED_ 13 | 14 | #if defined _MSC_VER 15 | #pragma warning(push) 16 | #pragma warning(disable : 4290) 17 | #endif 18 | 19 | #include 20 | #include 21 | 22 | #include "smartid_common.h" 23 | #include "smartid_result.h" 24 | 25 | /** 26 | * @mainpage Overview 27 | * The Smart ID Reader Library allows to recognize various ID documents 28 | * on images or video data obtained either from cameras or from scanners. 29 | * 30 | * This file contains a brief description of classes and members of the Library. 31 | * Sample usage is shown in the @c smartid_sample.cpp. 32 | * 33 | * Feel free to send any questions about the Library on 34 | * support@smartengines.biz. 35 | */ 36 | 37 | namespace se { namespace smartid { 38 | 39 | /** 40 | * @brief The SessionSettings class - runtime parameters of the recognition 41 | * session 42 | */ 43 | class SMARTID_DLL_EXPORT SessionSettings { 44 | public: 45 | /// SessionSettings dtor 46 | virtual ~SessionSettings(); 47 | 48 | /** 49 | * @brief Clones session settings and creates a new object on heap 50 | * @return new allocated object which is a copy of this 51 | */ 52 | virtual SessionSettings * Clone() const = 0; 53 | 54 | /** 55 | * @brief Get enabled document types with which recognition session will be created 56 | * @return a vector of enabled document types (exact types without wildcards) 57 | */ 58 | const std::vector& GetEnabledDocumentTypes() const; 59 | 60 | /** 61 | * @brief Add enabled document types conforming to GetSupportedDocumentTypes(). 62 | * Both exact string type names or wildcard expression can be used, for example: 63 | * "rus.passport.national", "rus.*", "*.passport.*", "*" 64 | * @param doctype_mask Document type name or wildcard expression 65 | */ 66 | void AddEnabledDocumentTypes(const std::string &doctype_mask); 67 | 68 | /** 69 | * @brief Remove enabled document types conforming to GetEnabledDocumentTypes(). 70 | * Both exact string type names or wildcard expression can be used, for example: 71 | * "rus.passport.national", "rus.*", "*.passport.*", "*" 72 | * @param doctype_mask Document type name or wildcard expression 73 | */ 74 | void RemoveEnabledDocumentTypes(const std::string &doctype_mask); 75 | 76 | /** 77 | * @brief Set enabled document types. Clears all enabled types and then calls 78 | * AddEnabledDocumentTypes() for each document type in the document_types 79 | * @param document_types a vector of enabled document types 80 | */ 81 | void SetEnabledDocumentTypes(const std::vector& document_types); 82 | 83 | /** 84 | * @brief Gets all supported document types for each engine of configured bundle. 85 | * Recognition session can only be spawned with the set of document 86 | * types corresponding to some single engine. 87 | * @return [engine][i_doctype_string] two dimensional vector const ref 88 | */ 89 | const std::vector >& GetSupportedDocumentTypes() const; 90 | 91 | /** 92 | * @brief Get full map of additional session settings 93 | * @return constref map of additional options 94 | * 95 | * @details Option name is a string consisting of two components: 96 | * <INTERNAL_ENGINE>.<OPTION_NAME>. Option value syntax is 97 | * dependent on the option, see full documentation for the 98 | * full list. 99 | */ 100 | const std::map& GetOptions() const; 101 | 102 | /** 103 | * @brief Get full map of additional session settings 104 | * @return ref map of additional options 105 | */ 106 | std::map& GetOptions(); 107 | 108 | /** 109 | * @brief Get all option names 110 | * @return vector of all additional option names 111 | */ 112 | std::vector GetOptionNames() const; 113 | 114 | /** 115 | * @brief Checks is there is a set additional option by name 116 | * @param name - string representation of option name 117 | * @return true if there is a set option with provided name 118 | */ 119 | bool HasOption(const std::string& name) const; 120 | 121 | /** 122 | * @brief Get an additional option value by name 123 | * @param name - string representation of option name 124 | * @return string value of an option 125 | * 126 | * @throws std::invalid_argument if there is no such option 127 | */ 128 | const std::string& GetOption( 129 | const std::string& name) const throw(std::exception); 130 | 131 | /** 132 | * @brief Set(modify) an additional option value by name 133 | * @param name - string representation of option name 134 | * @param value - value of option to set 135 | */ 136 | void SetOption(const std::string& name, const std::string& value); 137 | 138 | /** 139 | * @brief Remove an option from session settings (by name) 140 | * @param name - string representation of option name 141 | * 142 | * @throws std::invalid_argument if there is no such option 143 | */ 144 | void RemoveOption(const std::string& name) throw(std::exception); 145 | 146 | protected: 147 | std::vector > supported_document_types_; 148 | std::vector enabled_document_types_; 149 | std::map options_; 150 | 151 | /// Disabled default constructor - use RecognitionEngine factory method instead 152 | SessionSettings(); 153 | }; 154 | 155 | /** 156 | * @brief RecognitionSession class - 157 | * main interface for SmartID document recognition in videostream 158 | */ 159 | class SMARTID_DLL_EXPORT RecognitionSession { 160 | public: 161 | /// RecognitionSession dtor 162 | virtual ~RecognitionSession() { } 163 | 164 | /** 165 | * @brief Processes the uncompressed RGB image stored in memory line by line 166 | * @param data Pointer to the data buffer beginning 167 | * @param data_length Length of the data buffer 168 | * @param width Image width 169 | * @param height Image height 170 | * @param stride Difference between the pointers to the 171 | * consequent image lines, in bytes 172 | * @param channels Number of channels (1, 3 or 4). 1-channel image 173 | * is treated as grayscale image, 3-channel image 174 | * is treated as RGB image, 4-channel image is 175 | * treated as BGRA. 176 | * @param roi Rectangle of interest (the system will not 177 | * process anything outside this rectangle) 178 | * @param image_orientation Current image orientation to perform proper 179 | * rotation to landscape 180 | * 181 | * @return recognition result (integrated in the session) 182 | * @throws std::exception If processing error occurs 183 | */ 184 | virtual RecognitionResult ProcessSnapshot( 185 | unsigned char* data, 186 | size_t data_length, 187 | int width, 188 | int height, 189 | int stride, 190 | int channels, 191 | const Rectangle& roi, 192 | ImageOrientation image_orientation = Landscape) throw(std::exception) = 0; 193 | 194 | /** 195 | * @brief Processes the uncompressed RGB image stored in memory line by line. 196 | * Same as ProcessSnapshot with ROI, but with this method the ROI is 197 | * full image. 198 | * @param data Pointer to the data buffer beginning 199 | * @param data_length Length of the data buffer 200 | * @param width Image width 201 | * @param height Image height 202 | * @param stride Difference between the pointers to the 203 | * consequent image lines, in bytes 204 | * @param channels Number of channels (1, 3 or 4). 1-channel image 205 | * is treated as grayscale image, 3-channel image 206 | * is treated as RGB image, 4-channel image is 207 | * treated as BGRA. 208 | * @param image_orientation Current image orientation to perform proper 209 | * rotation to landscape 210 | * 211 | * @return recognition result (integrated in the session) 212 | * @throws std::exception If processing error occurs 213 | */ 214 | virtual RecognitionResult ProcessSnapshot( 215 | unsigned char* data, 216 | size_t data_length, 217 | int width, 218 | int height, 219 | int stride, 220 | int channels, 221 | ImageOrientation image_orientation = Landscape) throw(std::exception); 222 | 223 | /** 224 | * @brief Processes the uncompressed YUV image stored in memory line by line 225 | * @param yuv_data Pointer to the data buffer start 226 | * @param yuv_data_length Total length of image data buffer 227 | * @param width Image width 228 | * @param height Image height 229 | * @param roi Rectangle of interest (the system will not 230 | * process anything outside this rectangle) 231 | * @param image_orientation Current image orientation to perform proper 232 | * rotation to landscape 233 | * 234 | * @return recognition result (integrated in the session) 235 | * @throws std::exception If processing error occurs 236 | */ 237 | virtual RecognitionResult ProcessYUVSnapshot( 238 | unsigned char* yuv_data, 239 | size_t yuv_data_length, 240 | int width, 241 | int height, 242 | const Rectangle& roi, 243 | ImageOrientation image_orientation = Landscape) throw(std::exception); 244 | 245 | /** 246 | * @brief Processes the uncompressed YUV image stored in memory line by line. 247 | * Same as ProcessYUVSnapshot with ROI, but with this method the ROI 248 | * is full image 249 | * @param yuv_data Pointer to the data buffer start 250 | * @param yuv_data_length Total length of image data buffer 251 | * @param width Image width 252 | * @param height Image height 253 | * @param image_orientation Current image orientation to perform proper 254 | * rotation to landscape 255 | * 256 | * @return recognition result (integrated in the session) 257 | * @throws std::exception If processing error occurs 258 | */ 259 | virtual RecognitionResult ProcessYUVSnapshot( 260 | unsigned char* yuv_data, 261 | size_t yuv_data_length, 262 | int width, 263 | int height, 264 | ImageOrientation image_orientation = Landscape) throw(std::exception); 265 | 266 | /** 267 | * @brief Runs recognition process on the specified smartid::Image 268 | * @param image An Image to process 269 | * @param roi Rectangle of interest (the system will not 270 | * process anything outside this rectangle) 271 | * @param image_orientation Current image orientation to perform proper 272 | * rotation to landscape 273 | * 274 | * @return recognition result (integrated in the session) 275 | * @throws std::exception If file doesn't exist or can't be processed, or 276 | * if processing error occurs 277 | */ 278 | virtual RecognitionResult ProcessImage( 279 | const Image& image, 280 | const Rectangle& roi, 281 | ImageOrientation image_orientation = Landscape) throw(std::exception); 282 | 283 | /** 284 | * @brief Runs recognition process on the specified smartid::Image. 285 | * Same as ProcessImage with ROI, but with this method the ROI is 286 | * full image 287 | * @param image An Image to process 288 | * @param image_orientation Current image orientation to perform proper 289 | * rotation to landscape 290 | * 291 | * @return recognition result (integrated in the session) 292 | * @throws std::exception If file doesn't exist or can't be processed, or 293 | * if processing error occurs 294 | */ 295 | virtual RecognitionResult ProcessImage( 296 | const Image& image, 297 | ImageOrientation image_orientation = Landscape) throw(std::exception); 298 | 299 | /** 300 | * @brief Runs recognition process on the specified file 301 | * @param image_file Image file path 302 | * @param roi Rectangle of interest (the system will not 303 | * process anything outside this rectangle) 304 | * @param image_orientation Current image orientation to perform proper 305 | * rotation to landscape 306 | * 307 | * @return recognition result (integrated in the session) 308 | * @throws std::exception If file doesn't exist or can't be processed, or 309 | * if processing error occurs 310 | */ 311 | virtual RecognitionResult ProcessImageFile( 312 | const std::string& image_file, 313 | const Rectangle& roi, 314 | ImageOrientation image_orientation = Landscape) throw(std::exception); 315 | 316 | /** 317 | * @brief Runs recognition process on the specified file. 318 | * Same as ProcessImageFile with ROI, but with this method the ROI is 319 | * full image 320 | * @param image_file Image file path 321 | * @param image_orientation Current image orientation to perform proper 322 | * rotation to landscape 323 | * 324 | * @return recognition result (integrated in the session) 325 | * @throws std::exception If file doesn't exist or can't be processed, or 326 | * if processing error occurs 327 | */ 328 | virtual RecognitionResult ProcessImageFile( 329 | const std::string& image_file, 330 | ImageOrientation image_orientation = Landscape) throw(std::exception); 331 | 332 | /** 333 | * @brief Resets the internal state of the session 334 | */ 335 | virtual void Reset() = 0; 336 | }; 337 | 338 | /** 339 | * @brief The RecognitionEngine class - a factory for RecognitionSessions, 340 | * holds configured internal engines. 341 | */ 342 | class SMARTID_DLL_EXPORT RecognitionEngine { 343 | public: 344 | /** 345 | * @brief RecognitionEngine ctor from configuration path 346 | * @param config_path - path to configuration file 347 | * 348 | * @throws std::exception if configuration error occurs 349 | */ 350 | RecognitionEngine(const std::string& config_path) throw(std::exception); 351 | 352 | /** 353 | * @brief RecognitionEngine ctor from configuration buffer. Only for 354 | * configuration from ZIP archive buffers. 355 | * @param config_data - pointer to configuration ZIP buffer start 356 | * @param data_length - size of the configuration ZIP buffer 357 | * 358 | * @throws std::exception if configuration error occurs 359 | */ 360 | RecognitionEngine(unsigned char* config_data, 361 | size_t data_length) throw(std::exception); 362 | 363 | /// Recognition Engine dtor 364 | ~RecognitionEngine(); 365 | 366 | /** 367 | * @brief Factory method for creating 'default' session settings 368 | * with options loaded from configured bundle and no enabled documents 369 | * @return Allocated session settings, caller is responsible for destruction 370 | * @throws std::exception if settings creation failed 371 | */ 372 | SessionSettings* CreateSessionSettings() const throw(std::exception); 373 | 374 | /// Sessions for videostream recognition (one document - multiple frames) 375 | 376 | /** 377 | * @brief Factory method for creating a session for SmartId internal engine 378 | * @param session_settings - runtime session settings 379 | * @param result_reporter - pointer to optional processing reporter 380 | * implementation 381 | * 382 | * @return pointer to created recognition session. The caller is responsible 383 | * for session's destruction. 384 | * @throws std::exception if session creation failed 385 | */ 386 | RecognitionSession* SpawnSession( 387 | const SessionSettings& session_settings, 388 | ResultReporterInterface* result_reporter = 0) const throw(std::exception); 389 | 390 | /** 391 | * @brief Gets RecognitionEngine library version 392 | * @return std::string version representation 393 | */ 394 | static std::string GetVersion(); 395 | 396 | private: 397 | /// Disabled copy constructor 398 | RecognitionEngine(const RecognitionEngine& copy); 399 | /// Disabled assignment operator 400 | void operator=(const RecognitionEngine& other); 401 | 402 | private: 403 | class RecognitionEngineImpl* pimpl_; ///< pointer to internal implementation 404 | }; 405 | } } // namespace se::smartid 406 | 407 | #if defined _MSC_VER 408 | #pragma warning(pop) 409 | #endif 410 | 411 | #endif // SMARTID_ENGINE_SMARTID_ENGINE_H_INCLUDED 412 | -------------------------------------------------------------------------------- /SESmartIDCore/include/smartIdEngine/smartid_result.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2012-2017, Smart Engines Ltd 3 | * All rights reserved. 4 | */ 5 | 6 | /** 7 | * @file smartid_result.h 8 | * @brief Recognition result classes 9 | */ 10 | 11 | #ifndef SMARTID_ENGINE_SMARTID_RESULT_H_INCLUDED_ 12 | #define SMARTID_ENGINE_SMARTID_RESULT_H_INCLUDED_ 13 | 14 | #if defined _MSC_VER 15 | #pragma warning(push) 16 | #pragma warning(disable : 4290) 17 | #endif 18 | 19 | #include "smartid_common.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | namespace se { namespace smartid { 27 | 28 | /** 29 | * @brief Possible character recognition result 30 | */ 31 | class SMARTID_DLL_EXPORT OcrCharVariant { 32 | public: 33 | /** 34 | * @brief Default ctor 35 | */ 36 | OcrCharVariant(); 37 | 38 | /// OcrCharVariant dtor 39 | ~OcrCharVariant() {} 40 | 41 | /** 42 | * @brief Ctor from utf16 character and confidence 43 | * @param utf16_char - Utf16-character of a symbol 44 | * @param confidence - double confidence in range [0..1] 45 | * 46 | * @throw std::invalid_argument if confidence is not in range [0..1] 47 | */ 48 | OcrCharVariant(uint16_t utf16_char, double confidence) throw(std::exception); 49 | 50 | /** 51 | * @brief Ctor from utf8 character and confidence 52 | * @param utf8_char - utf8-representation of a 2-byte symbol in std::string 53 | * form 54 | * @param confidence - double confidence in range [0..1] 55 | * 56 | * @throw std::invalid_argument if confidence is not in range [0..1] or 57 | * if utf8_char is not a correct utf8 representation of 2-byte symbol 58 | */ 59 | OcrCharVariant(const std::string& utf8_char, 60 | double confidence) throw(std::exception); 61 | 62 | /// Getter for character in Utf16 form 63 | uint16_t GetUtf16Character() const; 64 | /// Getter for character in Utf8 form 65 | std::string GetUtf8Character() const; 66 | /// Variant confidence (pseudoprobability), in range [0..1] 67 | double GetConfidence() const; 68 | 69 | private: 70 | uint16_t character_; 71 | double confidence_; 72 | }; 73 | 74 | /** 75 | * @brief Contains all OCR information for a given character 76 | */ 77 | class SMARTID_DLL_EXPORT OcrChar { 78 | public: 79 | /** 80 | * @brief Default ctor 81 | */ 82 | OcrChar(); 83 | 84 | /** 85 | * @brief Main ctor 86 | * @param ocr_char_variants - vector of char variants 87 | * @param is_highlighted - whether this OcrChar is highlighted as unconfident 88 | * @param is_corrected - whether this OcrChar was corrected by post-processing 89 | */ 90 | OcrChar(const std::vector& ocr_char_variants, 91 | bool is_highlighted, bool is_corrected); 92 | 93 | /// OcrChar dtor 94 | ~OcrChar() {} 95 | 96 | /// Vector with possible recognition results for a given character 97 | const std::vector& GetOcrCharVariants() const; 98 | 99 | /// Whether this character is 'highlighted' (not confident) by the system 100 | bool IsHighlighted() const; 101 | /// Whether this character was changed by context correction (postprocessing) 102 | bool IsCorrected() const; 103 | 104 | /** 105 | * @brief Returns the most confident character as 16-bit utf16 character 106 | * 107 | * @throws std::out_of_range if variants are empty 108 | */ 109 | uint16_t GetUtf16Character() const throw(std::exception); 110 | 111 | /** 112 | * @brief Returns the most confident character as utf8 representation of 113 | * 16-bit character 114 | * 115 | * @throws std::out_of_range if variants are empty 116 | */ 117 | std::string GetUtf8Character() const throw(std::exception); 118 | 119 | private: 120 | std::vector ocr_char_variants_; 121 | bool is_highlighted_; 122 | bool is_corrected_; 123 | }; 124 | 125 | /** 126 | * @brief Contains additional OCR information for the whole string 127 | */ 128 | class SMARTID_DLL_EXPORT OcrString { 129 | public: 130 | /// Default ctor 131 | OcrString(); 132 | /// Ctor from vector of OcrChars 133 | OcrString(const std::vector& ocr_chars); 134 | /** 135 | * @brief OcrString ctor from plain utf8 string 136 | */ 137 | OcrString(const std::string& utf8_string); 138 | /// OcrString dtor 139 | ~OcrString() {} 140 | 141 | /// Vector with OCR information for each character 142 | const std::vector& GetOcrChars() const; 143 | 144 | /// Returns the most-confident string representation 145 | std::string GetUtf8String() const; 146 | 147 | /// Returns the most-confident string representation 148 | std::vector GetUtf16String() const; 149 | 150 | private: 151 | std::vector ocr_chars_; 152 | }; 153 | 154 | /** 155 | * @brief Class represents implementation of SmartID document Field for string 156 | * fields 157 | */ 158 | class SMARTID_DLL_EXPORT StringField { 159 | public: 160 | /** 161 | * @brief Default constructor 162 | */ 163 | StringField(); 164 | 165 | /** 166 | * @brief StringField main ctor 167 | * @param name - name of the field 168 | * @param value - OcrString-representation of the field value 169 | * @param is_accepted - whether the system is confident in the field's value 170 | * @param confidence - system's confidence level in fields' value in range 171 | * [0..1] 172 | * 173 | * @throws std::invalid_argument if confidence value is not in range [0..1] 174 | */ 175 | StringField(const std::string& name, const OcrString& value, bool is_accepted, 176 | double confidence) throw(std::exception); 177 | 178 | /** 179 | * @brief StringField ctor from utf8-string value 180 | * @param name - name of the field 181 | * @param value - utf8-string representation of the field value 182 | * @param is_accepted - whether the system is confident in the field's value 183 | * @param confidence - system's confidence level in fields' value in range 184 | * [0..1] 185 | * 186 | * @throws std::invalid_argument if confidence value is not in range [0..1] or 187 | * if failed to decode utf8-string 'value' 188 | */ 189 | StringField(const std::string& name, const std::string& value, 190 | bool is_accepted, double confidence) throw(std::exception); 191 | 192 | /** 193 | * @brief StringField ctor from utf8-string value (with raw value) 194 | * @param name - name of the field 195 | * @param value - utf8-string representation of the field value 196 | * @param raw_value - utf8-string representation of the field raw value 197 | * @param is_accepted - whether the system is confident in the field's value 198 | * @param confidence - system's confidence level in fields' value in range 199 | * [0..1] 200 | * 201 | * @throws std::invalid_argument if confidence value is not in range [0..1] or 202 | * if failed to decode utf8-string 'value' 203 | */ 204 | StringField(const std::string& name, const std::string& value, 205 | const std::string& raw_value, bool is_accepted, double confidence) 206 | throw(std::exception); 207 | 208 | /// Getter for string field name 209 | const std::string& GetName() const; 210 | /// Getter for string field value (OcrString representation) 211 | const OcrString& GetValue() const; 212 | /// Getter for string field value (Utf8-string representation) 213 | std::string GetUtf8Value() const; 214 | /// Getter for string field raw(without postprocessing) value (OcrString representation) 215 | const OcrString& GetRawValue() const; 216 | /// Getter for string field raw(without postprocessing) value (Utf8-string representation) 217 | std::string GetUtf8RawValue() const; 218 | /// Whether the system is confidence in field recognition result 219 | bool IsAccepted() const; 220 | /// The system's confidence level in field recognition result (in range 221 | /// [0..1]) 222 | double GetConfidence() const; 223 | 224 | private: 225 | std::string name_; ///< Field name 226 | OcrString value_; ///< Fields' OcrString value 227 | OcrString raw_value_; ///< Fields' OcrString raw value(without postprocessing) 228 | 229 | /// Specifies whether the system is confident in field recognition result 230 | bool is_accepted_; 231 | /// Specifies the system's confidence level in field recognition result 232 | double confidence_; 233 | }; 234 | 235 | /** 236 | * @brief Class represents implementation of SmartIDField for list of images 237 | */ 238 | class SMARTID_DLL_EXPORT ImageField { 239 | public: 240 | /** 241 | * @brief ImageField Default ctor 242 | */ 243 | ImageField(); 244 | 245 | /** 246 | * @brief ImageField main ctor 247 | * @param name - name of the field 248 | * @param value - image (the field result) 249 | * @param is_accepted - whether the system is confident in the field's value 250 | * @param confidence - system's confidence level in fields' value in range 251 | * [0..1] 252 | * 253 | * @throws std::invalid_argument if confidence value is not in range [0..1] or 254 | * if failed to decode utf8-string 'value' 255 | */ 256 | ImageField(const std::string& name, const Image& value, bool is_accepted, 257 | double confidence) throw(std::exception); 258 | 259 | /// Default dtor 260 | ~ImageField() {} 261 | 262 | /// Getter for image field name 263 | const std::string& GetName() const; 264 | /// Getter for image field result 265 | const Image& GetValue() const; 266 | /// Whether the system is confidence in field result 267 | bool IsAccepted() const; 268 | /// The system's confidence level in field result (in range [0..1]) 269 | double GetConfidence() const; 270 | 271 | private: 272 | std::string name_; 273 | Image value_; 274 | 275 | bool is_accepted_; ///< Specifies whether the system is confident in result 276 | double confidence_; ///< Specifies the system's confidence level in result 277 | }; 278 | 279 | /** 280 | * @brief Class represents SmartID match result 281 | */ 282 | class SMARTID_DLL_EXPORT MatchResult { 283 | public: 284 | /** 285 | * @brief Default ctor 286 | */ 287 | MatchResult(); 288 | 289 | /** 290 | * @brief MatchResult main ctor 291 | * @param tpl_type - template type for this match result 292 | * @param quadrangle - quadrangle of a template on image 293 | * @param accepted - acceptance for visualization 294 | */ 295 | MatchResult(const std::string& tpl_type, 296 | const Quadrangle& quadrangle, 297 | bool accepted = false); 298 | 299 | /// Default dtor 300 | ~MatchResult() {} 301 | 302 | /// Getter for document type string 303 | const std::string& GetTemplateType() const; 304 | /// Getter for document quadrangle 305 | const Quadrangle& GetQuadrangle() const; 306 | /// Getter for acceptance field 307 | bool GetAccepted() const; 308 | 309 | public: 310 | std::string template_type_; ///< Template type for this match result 311 | Quadrangle quadrangle_; ///< Quadrangle for this template 312 | bool accepted_; ///< Whether this result is ready to be visualized 313 | }; 314 | 315 | /** 316 | * @brief Class represents SmartID segmentation result containing 317 | * found zones/fields location information 318 | */ 319 | class SMARTID_DLL_EXPORT SegmentationResult { 320 | public: 321 | /// Default constructor 322 | SegmentationResult(); 323 | 324 | /// Main constructor 325 | SegmentationResult(const std::map& zone_quadrangles, 326 | bool accepted = false); 327 | 328 | /// Destructor 329 | ~SegmentationResult(); 330 | 331 | /// Getter for zone names which are keys for ZoneQuadrangles map 332 | std::vector GetZoneNames() const; 333 | 334 | /// Checks if there is a zone quadrangle with given zone_name 335 | bool HasZoneQuadrangle(const std::string &zone_name) const; 336 | 337 | /** 338 | * @brief Get zone quadrangle for zone name 339 | * @param zone_name zone name 340 | * @return Zone quadrangle for zone name 341 | * @throws std::invalid_argument if zone_name is not present in zone quadrangles 342 | */ 343 | const Quadrangle& GetZoneQuadrangle(const std::string &zone_name) const throw (std::exception); 344 | 345 | /// Getter for zone quadrangles (zone name -> quadrangle] 346 | const std::map& GetZoneQuadrangles() const; 347 | 348 | /** 349 | * @brief Gets field name corresponding to this zone 350 | * @param zone_name zone name 351 | * @return Field name for this zone, could be the same as zone_name 352 | * @throws std::invalid_argument if zone_name is not present in zone quadrangles 353 | */ 354 | std::string GetZoneFieldName(const std::string &zone_name) const throw (std::exception); 355 | 356 | /// Getter for accepted field 357 | bool GetAccepted() const; 358 | 359 | private: 360 | std::map zone_quadrangles_; ///< [zone name, quadrangle] 361 | bool accepted_; ///< Whether this result is ready to be visualized 362 | }; 363 | 364 | /** 365 | * @brief Class represents SmartID recognition result 366 | */ 367 | class SMARTID_DLL_EXPORT RecognitionResult { 368 | public: 369 | /** 370 | * @brief Default ctor 371 | */ 372 | RecognitionResult(); 373 | 374 | /** 375 | * @brief RecognitionResult main ctor 376 | */ 377 | RecognitionResult(const std::map& string_fields, 378 | const std::map& image_fields, 379 | const std::string& document_type, 380 | const std::vector& match_results, 381 | const std::vector& segmentation_results, 382 | bool is_terminal); 383 | 384 | /// RecognitionResult dtor 385 | ~RecognitionResult() {} 386 | 387 | /// Returns a vector of unique string field names 388 | std::vector GetStringFieldNames() const; 389 | /// Checks if there is a string field with given name 390 | bool HasStringField(const std::string& name) const; 391 | 392 | /** 393 | * @brief Gets string field by name 394 | * @param name - name of a string field 395 | * 396 | * @throws std::invalid_argument if there is no such field 397 | */ 398 | const StringField& GetStringField( 399 | const std::string& name) const throw(std::exception); 400 | 401 | /** 402 | * @brief Getter for string fields map 403 | * @return constref for string fields map 404 | */ 405 | const std::map& GetStringFields() const; 406 | 407 | /** 408 | * @brief Getter for (mutable) string fields map 409 | * @return ref for string fields map 410 | */ 411 | std::map& GetStringFields(); 412 | 413 | /** 414 | * @brief Setter for string fields map 415 | * @param string_fields - string fields map 416 | */ 417 | void SetStringFields(const std::map& string_fields); 418 | 419 | /// Returns a vector of unique image field names 420 | std::vector GetImageFieldNames() const; 421 | /// Checks if there is a image field with given name 422 | bool HasImageField(const std::string& name) const; 423 | 424 | /** 425 | * @brief Gets image field by name 426 | * @param name - name of an image field 427 | * 428 | * @throws std::invalid_argument if there is no such field 429 | */ 430 | const ImageField& GetImageField( 431 | const std::string& name) const throw(std::exception); 432 | 433 | /** 434 | * @brief Getter for image fields map 435 | * @return constref for image fields map 436 | */ 437 | const std::map& GetImageFields() const; 438 | 439 | /** 440 | * @brief Getter for (mutable) image fields map 441 | * @return ref for image fields map 442 | */ 443 | std::map& GetImageFields(); 444 | 445 | /** 446 | * @brief Setter for image fields map 447 | * @param image_fields - image fields map 448 | */ 449 | void SetImageFields(const std::map& image_fields); 450 | 451 | /// Getter for document type name. Empty string means empty result (no 452 | /// document match happened yet) 453 | const std::string& GetDocumentType() const; 454 | 455 | /// Setter for document type name 456 | void SetDocumentType(const std::string& doctype); 457 | 458 | /// Getter for match results - contains the most 'fresh' template quadrangles 459 | /// information available 460 | const std::vector& GetMatchResults() const; 461 | /// Setter for match results 462 | void SetMatchResults(const std::vector& match_results); 463 | 464 | /// Getter for segmentation results - contains the most 'fresh' zones 465 | /// and fields location information available 466 | const std::vector& GetSegmentationResults() const; 467 | /// Setter for segmentation results 468 | void SetSegmentationResults(const std::vector& segmentation_results); 469 | 470 | /** 471 | * @brief Whether the systems regards that result as 'final'. 472 | * Could be (optionally) used to stop the recognition session. 473 | */ 474 | bool IsTerminal() const; 475 | /// Setter for IsTerminal flag 476 | void SetIsTerminal(bool is_terminal); 477 | 478 | private: 479 | std::map string_fields_; 480 | std::map image_fields_; 481 | std::string document_type_; 482 | std::vector match_results_; 483 | std::vector segmentation_results_; 484 | bool is_terminal_; 485 | }; 486 | 487 | /** 488 | * @brief Callback interface to obtain recognition results. Must be implemented 489 | * to get the results as they appear during the stream processing 490 | */ 491 | class SMARTID_DLL_EXPORT ResultReporterInterface { 492 | public: 493 | 494 | /** 495 | * @brief Callback tells that last snapshot is not going to be 496 | * processed/recognized. Optional 497 | */ 498 | virtual void SnapshotRejected() {} 499 | 500 | /** 501 | * @brief Callback tells that last snapshot has valid document and 502 | contains document match result. Optional 503 | * @param match_result Document match result - vector of found templates 504 | */ 505 | virtual void DocumentMatched(const std::vector& match_results) {} 506 | 507 | /** 508 | * @brief Callback tells that last snapshot was segmented into fields and zones 509 | * for each match result. Optional. 510 | * @param segmentation_results Segmentation results for each corresponding MatchResult 511 | */ 512 | virtual void DocumentSegmented(const std::vector& segmentation_results) {} 513 | 514 | /** 515 | * @brief Callback tells that last snapshot was processed 516 | * successfully and returns current result. Required 517 | * @param recog_result Current recognition result 518 | */ 519 | virtual void SnapshotProcessed(const RecognitionResult& recog_result) = 0; 520 | 521 | /** 522 | * @brief Internal callback to stop the session (determined by internal timer) 523 | */ 524 | virtual void SessionEnded() {} 525 | 526 | /** 527 | * @brief Destructor 528 | */ 529 | virtual ~ResultReporterInterface() {} 530 | }; 531 | 532 | } } // namespace se::smartid 533 | 534 | #if defined _MSC_VER 535 | #pragma warning(pop) 536 | #endif 537 | 538 | #endif // SMARTID_ENGINE_SMARTID_RESULT_H_INCLUDED 539 | -------------------------------------------------------------------------------- /SESmartIDCore/lib/libsmartid-universal.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/90fdd5ff785b89be9f629230351f7ba906ccfbb5/SESmartIDCore/lib/libsmartid-universal.a -------------------------------------------------------------------------------- /SESmartIDSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | DB10A6941C90898E00C508CF /* SESIDQuadrangleView.mm in Sources */ = {isa = PBXBuildFile; fileRef = DB10A6931C90898E00C508CF /* SESIDQuadrangleView.mm */; }; 11 | DBBACF0D1A4D63FF00252642 /* SESIDSampleAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DBBACF0A1A4D63FF00252642 /* SESIDSampleAppDelegate.m */; }; 12 | DBBACF0F1A4D63FF00252642 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DBBACF0C1A4D63FF00252642 /* main.m */; }; 13 | DBBACF131A4D65AB00252642 /* SESIDSampleViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBBACF121A4D65AB00252642 /* SESIDSampleViewController.mm */; }; 14 | DBD8826D1A641C290056CC40 /* SESIDCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DBD882531A641C290056CC40 /* SESIDCameraManager.m */; }; 15 | DBD8826E1A641C290056CC40 /* SESIDRecognitionCore.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBD882551A641C290056CC40 /* SESIDRecognitionCore.mm */; }; 16 | DBD8826F1A641C290056CC40 /* SESIDRoiOverlayView.m in Sources */ = {isa = PBXBuildFile; fileRef = DBD882571A641C290056CC40 /* SESIDRoiOverlayView.m */; }; 17 | DBD882711A641C290056CC40 /* SESIDViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = DBD8825B1A641C290056CC40 /* SESIDViewController.mm */; }; 18 | DBD8827B1A6427360056CC40 /* libsmartid-universal.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBD8827A1A6427360056CC40 /* libsmartid-universal.a */; }; 19 | DBD8827D1A6691D40056CC40 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DBD8827C1A6691D40056CC40 /* Default-568h@2x.png */; }; 20 | DBEA4CCA1CF34BD1004C1835 /* data-zip in Resources */ = {isa = PBXBuildFile; fileRef = DBEA4CC91CF34BD1004C1835 /* data-zip */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | DB10A6921C90898E00C508CF /* SESIDQuadrangleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDQuadrangleView.h; sourceTree = ""; }; 25 | DB10A6931C90898E00C508CF /* SESIDQuadrangleView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SESIDQuadrangleView.mm; sourceTree = ""; }; 26 | DBBACEDF1A4C495300252642 /* SESmartIDSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SESmartIDSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | DBBACF091A4D63FF00252642 /* SESIDSampleAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDSampleAppDelegate.h; sourceTree = ""; }; 28 | DBBACF0A1A4D63FF00252642 /* SESIDSampleAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SESIDSampleAppDelegate.m; sourceTree = ""; }; 29 | DBBACF0B1A4D63FF00252642 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 30 | DBBACF0C1A4D63FF00252642 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 31 | DBBACF111A4D65AB00252642 /* SESIDSampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDSampleViewController.h; sourceTree = ""; }; 32 | DBBACF121A4D65AB00252642 /* SESIDSampleViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SESIDSampleViewController.mm; sourceTree = ""; }; 33 | DBD882521A641C290056CC40 /* SESIDCameraManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDCameraManager.h; sourceTree = ""; }; 34 | DBD882531A641C290056CC40 /* SESIDCameraManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SESIDCameraManager.m; sourceTree = ""; }; 35 | DBD882541A641C290056CC40 /* SESIDRecognitionCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDRecognitionCore.h; sourceTree = ""; }; 36 | DBD882551A641C290056CC40 /* SESIDRecognitionCore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SESIDRecognitionCore.mm; sourceTree = ""; }; 37 | DBD882561A641C290056CC40 /* SESIDRoiOverlayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDRoiOverlayView.h; sourceTree = ""; }; 38 | DBD882571A641C290056CC40 /* SESIDRoiOverlayView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SESIDRoiOverlayView.m; sourceTree = ""; }; 39 | DBD8825A1A641C290056CC40 /* SESIDViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SESIDViewController.h; sourceTree = ""; }; 40 | DBD8825B1A641C290056CC40 /* SESIDViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SESIDViewController.mm; sourceTree = ""; }; 41 | DBD8827A1A6427360056CC40 /* libsmartid-universal.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libsmartid-universal.a"; sourceTree = ""; }; 42 | DBD8827C1A6691D40056CC40 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 43 | DBEA4CC91CF34BD1004C1835 /* data-zip */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "data-zip"; path = "SESmartIDCore/data-zip"; sourceTree = SOURCE_ROOT; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | DBBACEDC1A4C495300252642 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | DBD8827B1A6427360056CC40 /* libsmartid-universal.a in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | DBBACED61A4C495300252642 = { 59 | isa = PBXGroup; 60 | children = ( 61 | DBD882301A641C290056CC40 /* SESmartID */, 62 | DBBACF081A4D63FF00252642 /* SESmartIDSample */, 63 | DBBACEE01A4C495300252642 /* Products */, 64 | ); 65 | sourceTree = ""; 66 | }; 67 | DBBACEE01A4C495300252642 /* Products */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | DBBACEDF1A4C495300252642 /* SESmartIDSample.app */, 71 | ); 72 | name = Products; 73 | sourceTree = ""; 74 | }; 75 | DBBACF081A4D63FF00252642 /* SESmartIDSample */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | DBBACF101A4D657C00252642 /* Supporting Files */, 79 | DBBACF111A4D65AB00252642 /* SESIDSampleViewController.h */, 80 | DBBACF121A4D65AB00252642 /* SESIDSampleViewController.mm */, 81 | ); 82 | path = SESmartIDSample; 83 | sourceTree = ""; 84 | }; 85 | DBBACF101A4D657C00252642 /* Supporting Files */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | DBD8827C1A6691D40056CC40 /* Default-568h@2x.png */, 89 | DBBACF091A4D63FF00252642 /* SESIDSampleAppDelegate.h */, 90 | DBBACF0A1A4D63FF00252642 /* SESIDSampleAppDelegate.m */, 91 | DBBACF0C1A4D63FF00252642 /* main.m */, 92 | DBBACF0B1A4D63FF00252642 /* Info.plist */, 93 | ); 94 | name = "Supporting Files"; 95 | sourceTree = ""; 96 | }; 97 | DBD882301A641C290056CC40 /* SESmartID */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | DBEA4CC91CF34BD1004C1835 /* data-zip */, 101 | DBD882791A6427360056CC40 /* lib */, 102 | DBD8825A1A641C290056CC40 /* SESIDViewController.h */, 103 | DBD8825B1A641C290056CC40 /* SESIDViewController.mm */, 104 | DBD882521A641C290056CC40 /* SESIDCameraManager.h */, 105 | DBD882531A641C290056CC40 /* SESIDCameraManager.m */, 106 | DBD882541A641C290056CC40 /* SESIDRecognitionCore.h */, 107 | DBD882551A641C290056CC40 /* SESIDRecognitionCore.mm */, 108 | DBD882561A641C290056CC40 /* SESIDRoiOverlayView.h */, 109 | DBD882571A641C290056CC40 /* SESIDRoiOverlayView.m */, 110 | DB10A6921C90898E00C508CF /* SESIDQuadrangleView.h */, 111 | DB10A6931C90898E00C508CF /* SESIDQuadrangleView.mm */, 112 | ); 113 | path = SESmartID; 114 | sourceTree = ""; 115 | }; 116 | DBD882791A6427360056CC40 /* lib */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | DBD8827A1A6427360056CC40 /* libsmartid-universal.a */, 120 | ); 121 | name = lib; 122 | path = SESmartIDCore/lib; 123 | sourceTree = SOURCE_ROOT; 124 | }; 125 | /* End PBXGroup section */ 126 | 127 | /* Begin PBXNativeTarget section */ 128 | DBBACEDE1A4C495300252642 /* SESmartIDSample */ = { 129 | isa = PBXNativeTarget; 130 | buildConfigurationList = DBBACF021A4C495300252642 /* Build configuration list for PBXNativeTarget "SESmartIDSample" */; 131 | buildPhases = ( 132 | DBBACEDB1A4C495300252642 /* Sources */, 133 | DBBACEDC1A4C495300252642 /* Frameworks */, 134 | DBBACEDD1A4C495300252642 /* Resources */, 135 | ); 136 | buildRules = ( 137 | ); 138 | dependencies = ( 139 | ); 140 | name = SESmartIDSample; 141 | productName = SESmartID; 142 | productReference = DBBACEDF1A4C495300252642 /* SESmartIDSample.app */; 143 | productType = "com.apple.product-type.application"; 144 | }; 145 | /* End PBXNativeTarget section */ 146 | 147 | /* Begin PBXProject section */ 148 | DBBACED71A4C495300252642 /* Project object */ = { 149 | isa = PBXProject; 150 | attributes = { 151 | CLASSPREFIX = SESID; 152 | LastUpgradeCheck = 0800; 153 | ORGANIZATIONNAME = "Smart Engines Ltd"; 154 | TargetAttributes = { 155 | DBBACEDE1A4C495300252642 = { 156 | CreatedOnToolsVersion = 6.1.1; 157 | DevelopmentTeam = WWNR4RF9QW; 158 | }; 159 | }; 160 | }; 161 | buildConfigurationList = DBBACEDA1A4C495300252642 /* Build configuration list for PBXProject "SESmartIDSample" */; 162 | compatibilityVersion = "Xcode 3.2"; 163 | developmentRegion = English; 164 | hasScannedForEncodings = 0; 165 | knownRegions = ( 166 | en, 167 | Base, 168 | ); 169 | mainGroup = DBBACED61A4C495300252642; 170 | productRefGroup = DBBACEE01A4C495300252642 /* Products */; 171 | projectDirPath = ""; 172 | projectRoot = ""; 173 | targets = ( 174 | DBBACEDE1A4C495300252642 /* SESmartIDSample */, 175 | ); 176 | }; 177 | /* End PBXProject section */ 178 | 179 | /* Begin PBXResourcesBuildPhase section */ 180 | DBBACEDD1A4C495300252642 /* Resources */ = { 181 | isa = PBXResourcesBuildPhase; 182 | buildActionMask = 2147483647; 183 | files = ( 184 | DBEA4CCA1CF34BD1004C1835 /* data-zip in Resources */, 185 | DBD8827D1A6691D40056CC40 /* Default-568h@2x.png in Resources */, 186 | ); 187 | runOnlyForDeploymentPostprocessing = 0; 188 | }; 189 | /* End PBXResourcesBuildPhase section */ 190 | 191 | /* Begin PBXSourcesBuildPhase section */ 192 | DBBACEDB1A4C495300252642 /* Sources */ = { 193 | isa = PBXSourcesBuildPhase; 194 | buildActionMask = 2147483647; 195 | files = ( 196 | DBD8826D1A641C290056CC40 /* SESIDCameraManager.m in Sources */, 197 | DBBACF131A4D65AB00252642 /* SESIDSampleViewController.mm in Sources */, 198 | DBBACF0D1A4D63FF00252642 /* SESIDSampleAppDelegate.m in Sources */, 199 | DBD8826E1A641C290056CC40 /* SESIDRecognitionCore.mm in Sources */, 200 | DBD8826F1A641C290056CC40 /* SESIDRoiOverlayView.m in Sources */, 201 | DB10A6941C90898E00C508CF /* SESIDQuadrangleView.mm in Sources */, 202 | DBD882711A641C290056CC40 /* SESIDViewController.mm in Sources */, 203 | DBBACF0F1A4D63FF00252642 /* main.m in Sources */, 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | }; 207 | /* End PBXSourcesBuildPhase section */ 208 | 209 | /* Begin XCBuildConfiguration section */ 210 | DBBACF001A4C495300252642 /* Debug */ = { 211 | isa = XCBuildConfiguration; 212 | buildSettings = { 213 | ALWAYS_SEARCH_USER_PATHS = NO; 214 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 215 | CLANG_CXX_LIBRARY = "libc++"; 216 | CLANG_ENABLE_MODULES = YES; 217 | CLANG_ENABLE_OBJC_ARC = YES; 218 | CLANG_WARN_BOOL_CONVERSION = YES; 219 | CLANG_WARN_CONSTANT_CONVERSION = YES; 220 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 221 | CLANG_WARN_EMPTY_BODY = YES; 222 | CLANG_WARN_ENUM_CONVERSION = YES; 223 | CLANG_WARN_INFINITE_RECURSION = YES; 224 | CLANG_WARN_INT_CONVERSION = YES; 225 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 226 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 227 | CLANG_WARN_UNREACHABLE_CODE = YES; 228 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 229 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 230 | COPY_PHASE_STRIP = NO; 231 | ENABLE_STRICT_OBJC_MSGSEND = YES; 232 | ENABLE_TESTABILITY = YES; 233 | GCC_C_LANGUAGE_STANDARD = gnu99; 234 | GCC_DYNAMIC_NO_PIC = NO; 235 | GCC_NO_COMMON_BLOCKS = YES; 236 | GCC_OPTIMIZATION_LEVEL = 0; 237 | GCC_PREPROCESSOR_DEFINITIONS = ( 238 | "DEBUG=1", 239 | "$(inherited)", 240 | ); 241 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 242 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 243 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 244 | GCC_WARN_UNDECLARED_SELECTOR = YES; 245 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 246 | GCC_WARN_UNUSED_FUNCTION = YES; 247 | GCC_WARN_UNUSED_VARIABLE = YES; 248 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 249 | MTL_ENABLE_DEBUG_INFO = YES; 250 | ONLY_ACTIVE_ARCH = YES; 251 | SDKROOT = iphoneos; 252 | }; 253 | name = Debug; 254 | }; 255 | DBBACF011A4C495300252642 /* Release */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 260 | CLANG_CXX_LIBRARY = "libc++"; 261 | CLANG_ENABLE_MODULES = YES; 262 | CLANG_ENABLE_OBJC_ARC = YES; 263 | CLANG_WARN_BOOL_CONVERSION = YES; 264 | CLANG_WARN_CONSTANT_CONVERSION = YES; 265 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 266 | CLANG_WARN_EMPTY_BODY = YES; 267 | CLANG_WARN_ENUM_CONVERSION = YES; 268 | CLANG_WARN_INFINITE_RECURSION = YES; 269 | CLANG_WARN_INT_CONVERSION = YES; 270 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 271 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 272 | CLANG_WARN_UNREACHABLE_CODE = YES; 273 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 274 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 275 | COPY_PHASE_STRIP = YES; 276 | ENABLE_NS_ASSERTIONS = NO; 277 | ENABLE_STRICT_OBJC_MSGSEND = YES; 278 | GCC_C_LANGUAGE_STANDARD = gnu99; 279 | GCC_NO_COMMON_BLOCKS = YES; 280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 282 | GCC_WARN_UNDECLARED_SELECTOR = YES; 283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 284 | GCC_WARN_UNUSED_FUNCTION = YES; 285 | GCC_WARN_UNUSED_VARIABLE = YES; 286 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 287 | MTL_ENABLE_DEBUG_INFO = NO; 288 | SDKROOT = iphoneos; 289 | VALIDATE_PRODUCT = YES; 290 | }; 291 | name = Release; 292 | }; 293 | DBBACF031A4C495300252642 /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 297 | CODE_SIGN_IDENTITY = "iPhone Developer"; 298 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 299 | ENABLE_BITCODE = NO; 300 | HEADER_SEARCH_PATHS = ( 301 | "$(inherited)", 302 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 303 | "\"$(SRCROOT)/SESmartIDCore/include\"", 304 | ); 305 | INFOPLIST_FILE = "$(SRCROOT)/SESmartIDSample/Info.plist"; 306 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 307 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 308 | LIBRARY_SEARCH_PATHS = ( 309 | "$(inherited)", 310 | "$(PROJECT_DIR)/SESmartIDCore/lib", 311 | ); 312 | OTHER_LDFLAGS = ""; 313 | PRODUCT_BUNDLE_IDENTIFIER = "com.smartengines.$(PRODUCT_NAME:rfc1034identifier)"; 314 | PRODUCT_NAME = SESmartIDSample; 315 | PROVISIONING_PROFILE = ""; 316 | TARGETED_DEVICE_FAMILY = "1,2"; 317 | }; 318 | name = Debug; 319 | }; 320 | DBBACF041A4C495300252642 /* Release */ = { 321 | isa = XCBuildConfiguration; 322 | buildSettings = { 323 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 324 | CODE_SIGN_IDENTITY = "iPhone Developer"; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | ENABLE_BITCODE = NO; 327 | HEADER_SEARCH_PATHS = ( 328 | "$(inherited)", 329 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 330 | "\"$(SRCROOT)/SESmartIDCore/include\"", 331 | ); 332 | INFOPLIST_FILE = "$(SRCROOT)/SESmartIDSample/Info.plist"; 333 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 334 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 335 | LIBRARY_SEARCH_PATHS = ( 336 | "$(inherited)", 337 | "$(PROJECT_DIR)/SESmartIDCore/lib", 338 | ); 339 | OTHER_LDFLAGS = ""; 340 | PRODUCT_BUNDLE_IDENTIFIER = "com.smartengines.$(PRODUCT_NAME:rfc1034identifier)"; 341 | PRODUCT_NAME = SESmartIDSample; 342 | PROVISIONING_PROFILE = ""; 343 | TARGETED_DEVICE_FAMILY = "1,2"; 344 | }; 345 | name = Release; 346 | }; 347 | /* End XCBuildConfiguration section */ 348 | 349 | /* Begin XCConfigurationList section */ 350 | DBBACEDA1A4C495300252642 /* Build configuration list for PBXProject "SESmartIDSample" */ = { 351 | isa = XCConfigurationList; 352 | buildConfigurations = ( 353 | DBBACF001A4C495300252642 /* Debug */, 354 | DBBACF011A4C495300252642 /* Release */, 355 | ); 356 | defaultConfigurationIsVisible = 0; 357 | defaultConfigurationName = Release; 358 | }; 359 | DBBACF021A4C495300252642 /* Build configuration list for PBXNativeTarget "SESmartIDSample" */ = { 360 | isa = XCConfigurationList; 361 | buildConfigurations = ( 362 | DBBACF031A4C495300252642 /* Debug */, 363 | DBBACF041A4C495300252642 /* Release */, 364 | ); 365 | defaultConfigurationIsVisible = 0; 366 | defaultConfigurationName = Release; 367 | }; 368 | /* End XCConfigurationList section */ 369 | }; 370 | rootObject = DBBACED71A4C495300252642 /* Project object */; 371 | } 372 | -------------------------------------------------------------------------------- /SESmartIDSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SESmartIDSample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/90fdd5ff785b89be9f629230351f7ba906ccfbb5/SESmartIDSample/Default-568h@2x.png -------------------------------------------------------------------------------- /SESmartIDSample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.7.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 0 23 | LSRequiresIPhoneOS 24 | 25 | NSAppleMusicUsageDescription 26 | 27 | NSCameraUsageDescription 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIRequiresFullScreen 34 | 35 | UIStatusBarStyle 36 | UIStatusBarStyleLightContent 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationLandscapeRight 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /SESmartIDSample/SESIDSampleAppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | @interface SESIDSampleAppDelegate : UIResponder 32 | 33 | @property (strong, nonatomic) UIWindow *window; 34 | 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /SESmartIDSample/SESIDSampleAppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDSampleAppDelegate.h" 30 | #import "SESIDSampleViewController.h" 31 | 32 | @implementation SESIDSampleAppDelegate 33 | 34 | - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 35 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 36 | self.window.rootViewController = [[SESIDSampleViewController alloc] init]; 37 | [self.window makeKeyAndVisible]; 38 | return YES; 39 | } 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /SESmartIDSample/SESIDSampleViewController.h: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | 31 | @interface SESIDSampleViewController : UIViewController 32 | 33 | @property (nonatomic) UIButton *scanButton; 34 | @property (nonatomic) UITextView *resultTextView; 35 | @property (nonatomic) UIImageView *resultImageView; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /SESmartIDSample/SESIDSampleViewController.mm: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import "SESIDSampleViewController.h" 30 | 31 | #import "SESIDViewController.h" 32 | 33 | @interface SESIDSampleViewController () 34 | 35 | @property (strong, nonatomic) SESIDViewController *smartIdViewController; 36 | 37 | @end 38 | 39 | @implementation SESIDSampleViewController 40 | 41 | - (void) viewDidLoad { 42 | [super viewDidLoad]; 43 | 44 | [self addScanButton]; 45 | [self addResultTextView]; 46 | [self addResultImageView]; 47 | 48 | [self initializeSmartIdViewController]; 49 | } 50 | 51 | - (void) initializeSmartIdViewController { 52 | // core configuration may take a while so it's better to be done 53 | // before displaying smart id view controller 54 | self.smartIdViewController = [[SESIDViewController alloc] init]; 55 | 56 | // assigning self as delegate to get smartIdViewControlerDidRecognizeResult called 57 | self.smartIdViewController.delegate = self; 58 | 59 | // configure optional visualization properties (they are NO by default) 60 | self.smartIdViewController.displayDocumentQuadrangle = YES; 61 | self.smartIdViewController.displayZonesQuadrangles = YES; 62 | } 63 | 64 | - (void) showSmartIdViewController { 65 | if (!self.smartIdViewController) { 66 | [self initializeSmartIdViewController]; 67 | } 68 | 69 | // important! 70 | // setting enabled document types for this view controller 71 | // according to available document types for your delivery 72 | // these types will be passed to se::smartid::SessionSettings 73 | // with which se::smartid::RecognitionEngine::SpawnSession(...) is called 74 | // internally when Smart ID view controller is presented 75 | // you can specify a concrete document type or a wildcard expression (for convenience) 76 | // to enable or disable multiple types 77 | // by default no document types are enabled 78 | // if exception is thrown please read the exception message 79 | // see self.smartidViewController.supportedDocumentTypes, 80 | // se::smartid::SessionSettings and Smart IDReader documentation for further information 81 | [self.smartIdViewController removeEnabledDocumentTypesMask:"*"]; 82 | 83 | // [self.smartIdViewController addEnabledDocumentTypesMask:"*"]; 84 | [self.smartIdViewController addEnabledDocumentTypesMask:"mrz.*"]; 85 | // [self.smartIdViewController addEnabledDocumentTypesMask:"idmrz.*"]; 86 | // [self.smartIdViewController addEnabledDocumentTypesMask:"card.*"]; 87 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.passport.*"]; 88 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.snils.*"]; 89 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.sts.*"]; 90 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.drvlic.*"]; 91 | 92 | // if needed, set a timeout in seconds 93 | self.smartIdViewController.sessionTimeout = 5.0f; 94 | 95 | // presenting OCR view controller 96 | [self presentViewController:self.smartIdViewController 97 | animated:YES 98 | completion:nil]; 99 | 100 | // if you want to deinitialize view controller to save the memory, do this: 101 | // self.smartIdViewController = nil; 102 | } 103 | 104 | #pragma mark - SESIDViewControllerDelegate 105 | - (void) smartIdViewControllerDidRecognizeResult:(const se::smartid::RecognitionResult &)result { 106 | // if result is not terminal we'd probably want to continue recognition until it becomes terminal 107 | // you can also check individual fields using result.GetStringField("field_name").IsAccepted() 108 | // in order to conditionally stop recognition when required fields are accepted 109 | if (!result.IsTerminal()) { 110 | return; 111 | } 112 | 113 | // dismiss Smart ID OCR view controller 114 | [self dismissViewControllerAnimated:YES completion:nil]; 115 | 116 | // use recognition result 117 | NSMutableString *resultString = [[NSMutableString alloc] init]; 118 | 119 | // use string fields 120 | const std::vector &stringFieldNames = result.GetStringFieldNames(); 121 | [resultString appendString:[NSString stringWithFormat:@"\nFound %zu string fields:\n", 122 | stringFieldNames.size()]]; 123 | 124 | for (size_t i = 0; i < stringFieldNames.size(); ++i) { 125 | const se::smartid::StringField &field = result.GetStringField(stringFieldNames[i]); 126 | NSString *fieldValue = [NSString stringWithUTF8String:field.GetUtf8Value().c_str()]; 127 | NSString *fieldAccepted = (field.IsAccepted() ? @"[+]" : @"[-]"); 128 | NSString *fieldString = [NSString stringWithFormat:@"%@ %s: %@\n", 129 | fieldAccepted, field.GetName().c_str(), fieldValue]; 130 | [resultString appendString:fieldString]; 131 | } 132 | 133 | // use image fields 134 | const std::vector &imageFieldNames = result.GetImageFieldNames(); 135 | [resultString appendString:[NSString stringWithFormat:@"\nFound %zu image fields:\n", 136 | imageFieldNames.size()]]; 137 | for (size_t i = 0; i < imageFieldNames.size(); ++i) { 138 | const se::smartid::ImageField &field = result.GetImageField(imageFieldNames[i]); 139 | NSString *fieldAccepted = (field.IsAccepted() ? @"[+]" : @"[-]"); 140 | const se::smartid::Image &image = field.GetValue(); 141 | 142 | NSString *fieldString = [NSString stringWithFormat:@"%@ %s (%dx%d)\n", 143 | fieldAccepted, field.GetName().c_str(), image.width, image.height]; 144 | [resultString appendString:fieldString]; 145 | } 146 | 147 | const std::string photoName = "photo"; 148 | if (result.HasImageField(photoName)) { 149 | const se::smartid::Image &image = result.GetImageField(photoName).GetValue(); 150 | self.resultImageView.image = [SESIDViewController uiImageFromSmartIdImage:image]; 151 | } else { 152 | self.resultImageView.image = nil; 153 | } 154 | 155 | [self.resultTextView setText:resultString]; 156 | } 157 | 158 | - (void) smartIdViewControllerDidCancel { 159 | // dismiss Smart ID OCR view controller 160 | [self dismissViewControllerAnimated:YES completion:nil]; 161 | 162 | [self.resultTextView setText:@"Recognition cancelled by user"]; 163 | [self.resultImageView setImage:nil]; 164 | } 165 | 166 | #pragma mark - Misc 167 | - (void) viewDidLayoutSubviews { 168 | self.scanButton.frame = CGRectMake(0, 20, self.view.bounds.size.width, 50); 169 | 170 | const CGFloat imageWidth = 120; 171 | const CGFloat imageHeight = imageWidth * 3.0 / 2.0; 172 | 173 | self.resultTextView.frame = CGRectMake(0, 174 | CGRectGetMaxY(self.scanButton.frame) + 15, 175 | self.view.bounds.size.width, 176 | self.view.bounds.size.height 177 | - CGRectGetMaxY(self.scanButton.frame) - 15); 178 | 179 | const CGRect imageFrame = CGRectMake(self.resultTextView.bounds.size.width - imageWidth - 10, 180 | 10, 181 | imageWidth, imageHeight); 182 | self.resultImageView.frame = imageFrame; 183 | 184 | CGRect exclusionRect = imageFrame; 185 | exclusionRect.size.width = self.resultTextView.bounds.size.width; 186 | 187 | UIBezierPath *exclusionPath = [UIBezierPath bezierPathWithRect:exclusionRect]; 188 | self.resultTextView.textContainer.exclusionPaths = @[exclusionPath]; 189 | } 190 | 191 | - (void) addScanButton { 192 | self.scanButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 193 | [self.scanButton setBackgroundColor:UIColor.whiteColor]; 194 | [self.scanButton setAutoresizingMask:UIViewAutoresizingFlexibleWidth]; 195 | [self.scanButton setTitle:@"Press to Scan ID!" forState:UIControlStateNormal]; 196 | [self.scanButton addTarget:self 197 | action:@selector(showSmartIdViewController) 198 | forControlEvents:UIControlEventTouchUpInside]; 199 | [self.view addSubview:self.scanButton]; 200 | } 201 | 202 | - (void) addResultTextView { 203 | self.resultTextView = [[UITextView alloc] init]; 204 | self.resultTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight 205 | | UIViewAutoresizingFlexibleWidth; 206 | self.resultTextView.editable = NO; 207 | self.resultTextView.font = [UIFont fontWithName:@"Menlo-Regular" size:12.0f]; 208 | 209 | [self.view addSubview:self.resultTextView]; 210 | } 211 | 212 | - (void) addResultImageView { 213 | self.resultImageView = [[UIImageView alloc] init]; 214 | self.resultImageView.contentMode = UIViewContentModeScaleAspectFit; 215 | self.resultImageView.backgroundColor = [UIColor colorWithWhite:0.9f alpha:0.5f]; 216 | 217 | [self.resultTextView addSubview:self.resultImageView]; 218 | } 219 | 220 | - (BOOL) prefersStatusBarHidden { 221 | return NO; 222 | } 223 | 224 | - (UIStatusBarStyle) preferredStatusBarStyle { 225 | return UIStatusBarStyleLightContent; 226 | } 227 | 228 | - (UIInterfaceOrientationMask) supportedInterfaceOrientations { 229 | return UIInterfaceOrientationMaskAll; 230 | } 231 | 232 | @end 233 | -------------------------------------------------------------------------------- /SESmartIDSample/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (c) 2012-2017, Smart Engines Ltd 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, 9 | this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | * Neither the name of the Smart Engines Ltd nor the names of its 14 | contributors may be used to endorse or promote products derived from this 15 | software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 24 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | #import 30 | #import "SESIDSampleAppDelegate.h" 31 | 32 | int main(int argc, char * argv[]) { 33 | @autoreleasepool { 34 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SESIDSampleAppDelegate class])); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | This directory contains various documentation for Smart IDReader SDK. 2 | 3 | * [iOSIntegrationGuide.md](iOSIntegrationGuide.md) - Integration Guide for iOS 4 | * [SmartIDReaderSDK.md](SmartIDReaderSDK.md) - Detailed library overview 5 | * [DocumentsReference.md](DocumentsReference.md) - Complete description of document types, fields and formats supported by us 6 | * [smartIdEngine.pdf](smartIdEngine.pdf) - C++ library documentation 7 | 8 | Have any issues or questions? Feel free contact us at support@smartengines.biz! 9 | -------------------------------------------------------------------------------- /doc/SmartIDReaderSDK.md: -------------------------------------------------------------------------------- 1 | # Smart IDReader SDK 2 | 3 | * [Troubleshooting and help](#troubleshooting-and-help) 4 | * [General Usage Workflow](#general-usage-workflow) 5 | * [Smart IDReader C++ SDK Overview](#smart-idreader-c-sdk-overview) 6 | - [Header files and namespaces](#header-files-and-namespaces) 7 | - [Code documentation](#code-documentation) 8 | - [Exceptions](#exceptions) 9 | - [Factory methods and memory ownership](#factory-methods-and-memory-ownership) 10 | - [Getters and setters](#getters-and-setters) 11 | * [Configuration bundles](#configuration-bundles) 12 | * [Specifying document types for Recognition Session](#specifying-document-types-for-recognition-session) 13 | - [Supported document types](#supported-document-types) 14 | - [Enabling document types using wildcard expressions](#enabling-document-types-using-wildcard-expressions) 15 | * [Session options](#session-options) 16 | - [Common options](#common-options) 17 | * [Result Reporter Callbacks](#result-reporter-callbacks) 18 | * [Java API](#java-api) 19 | - [Object deallocation](#object-deallocation) 20 | - [Result Reporter Interface scope](#result-reporter-interface-scope) 21 | * [C API](#c-api) 22 | - [C memory management](#c-memory-management) 23 | - [Return codes and exception messages](#return-codes-and-exception-messages) 24 | * [Documents reference](./DOCUMENTS_REFERENCE.html) 25 | 26 | 27 | ## Troubleshooting and help 28 | 29 | To resolve issue that you might be facing we recommend to do the following: 30 | 31 | * Carefully read in-code documentation in API an samples and documentation in .pdf and .html including this document 32 | * Check out the code details / compilation flags etc in sample code and projects 33 | * Read exception messages if exception is thrown - it might contain usable information 34 | 35 | But remember: 36 | * You are always welcome to ask for help at `support@smartengines.biz` (or product manager's email) no matter what 37 | 38 | ## General Usage Workflow 39 | 40 | 1. Create `RecognitionEngine` instance: 41 | 42 | ```cpp 43 | se::smartid::RecognitionEngine engine(configuration_bundle_path); 44 | ``` 45 | 46 | Configuration process might take a while but it only needs to be performed once during the program lifetime. Configured `RecognitionEngine` is used to spawn lightweight Recognition Sessions which have actual recognition methods. 47 | 48 | See more about configuration bundles in [Configuration Bundles](#configuration-bundles). 49 | 50 | 2. Create `SessionSettings` from configured `RecognitionEngine`: 51 | 52 | ```cpp 53 | std::unique_ptr settings(engine.CreateSessionSettings()); 54 | ``` 55 | 56 | Note, that `RecognitionEngine::CreateSessionSettings()` is a factory method and returns an allocated pointer. You are responsible for deleting it. 57 | 58 | 3. Enable desired document types: 59 | 60 | ```cpp 61 | settings->AddEnabledDocumentTypes("mrz.*"); 62 | ``` 63 | 64 | See more about document types in [Specifying document types for Recognition Session](#specifying-document-types-for-recognition-session). 65 | 66 | 4. Specify session options (not required): 67 | 68 | ```cpp 69 | settings->SetOption("common.sessionTimeout", "5"); 70 | ``` 71 | 72 | See more about options in [Session Options](#session-options). 73 | 74 | 5. Subclass ResultReporter and implement callbacks (not required): 75 | 76 | ```cpp 77 | class ConcreteResultReporter : public se::smartid::ResultReporterInterface { /* callbacks */ } 78 | 79 | ConcreteResultReporter optional_reporter; 80 | ``` 81 | 82 | See more about result reporter callbacks in [Result Reporter Callbacks](#result-reporter-callbacks). 83 | 84 | 6. Spawn Recognition Session: 85 | 86 | ```cpp 87 | unique_ptr session(engine.SpawnSession(*settings, &optional_reporter)); 88 | ``` 89 | 90 | 7. Call `ProcessSnapshot(...)`, `ProcessImageFile(...)` or similar methods: 91 | 92 | ```cpp 93 | se::smartid::RecognitionResult result = session->ProcessImageFile(image_path); 94 | ``` 95 | 96 | When performing recognition in video stream you might want to process frames coming from the stream until `result.IsTerminal()` is `true`. 97 | 98 | 8. Use `RecognitionResult` fields to extract recognized information: 99 | 100 | ```cpp 101 | for (const std::string &field_name : result.GetStringFieldNames()) { 102 | const se::smartid::StringField &string_field = result.GetStringField(field_name); 103 | 104 | bool is_accepted = string_field.IsAccepted(); 105 | std::string field_value = string_field.GetUtf8Value(); 106 | } 107 | ``` 108 | 109 | Apart from string fields there also are image fields: 110 | 111 | ```cpp 112 | for (const std::string &field_name : result.GetImageFieldNames()) { 113 | const se::smartid::ImageField &image_field = result.GetStringField(field_name); 114 | 115 | const se::smartid::Image &image = image_field.GetValue(); 116 | } 117 | ``` 118 | 119 | 120 | ## Smart IDReader C++ SDK Overview 121 | 122 | #### Header files and namespaces 123 | 124 | You can either include all-in-one header file or only required ones: 125 | 126 | ```cpp 127 | #include // all-in-one 128 | #include // common classes 129 | #include // result classes 130 | ``` 131 | 132 | Smart IDReader C++ SDK code is located within `se::smartid` namespace. 133 | 134 | #### Code documentation 135 | 136 | All classes and functions have useful Doxygen comments. 137 | Other out-of-code documentation is available at `doc` folder of your delivery. 138 | For complete compilable and runnable sample usage code and build scripts please see `samples` folder. 139 | 140 | #### Exceptions 141 | 142 | Our C++ API may throw `std::exception` subclasses when user passes invalid input, makes bad state calls or if something else goes wrong. Most exceptions contain useful human-readable information. Please read `e.what()` message if exception is thrown. 143 | 144 | #### Factory methods and memory ownership 145 | 146 | Several Smart IDReader SDK classes have factory methods which return pointers to heap-allocated objects. **Caller is responsible for deleting** such objects _(a caller is probably the one who is reading this right now)_. 147 | We recommend using `std::unique_ptr` for simple memory management and avoiding memory leaks. 148 | 149 | #### Getters and setters 150 | 151 | We return const references in getters wherever possible, it's better to assign them to const references as well to avoid undesirable copying. If there is only getter without setter for some variable then most probably we did this by purpose because configuration is done somewhere else internally. 152 | 153 | ## Configuration bundles 154 | 155 | Every delivery contains one or several _configuration bundles_ – archives containing everything needed for Smart IDReader Recognition Engine to be created and configured. 156 | Usually they are named as `bundle_something.zip` and located inside `data-zip` folder. 157 | 158 | ## Specifying document types for Recognition Session 159 | 160 | Assuming you already created recognition engine and session settings like this: 161 | 162 | ```cpp 163 | // create recognition engine with configuration bundle path 164 | se::smartid::RecognitionEngine engine(configuration_bundle_path); 165 | 166 | // create session settings with se::smartid::RecognitionEngine factory method 167 | std::unique_ptr settings(engine.CreateSessionSettings()); 168 | ``` 169 | 170 | In order to call `engine.SpawnSession(settings, optional_reporter)` you need to specify enabled document types for session to be spawned using `se::smartid::SessionSettings` methods. 171 | **By default, all document types are disabled.** 172 | 173 | #### Supported document types 174 | 175 | A _document type_ is simply a string encoding real world document type you want to recognize, for example, `rus.passport.internal` or `mrz.mrp`. Document types that Smart IDReader SDK delivered to you can potentially recognize can be obtaining using `GetSupportedDocumentTypes()` method: 176 | 177 | ```cpp 178 | const vector > &supported_document_types = settings->GetSupportedDocumentTypes(); 179 | ``` 180 | 181 | This vector is two-dimensional because of the restrictions of current Smart IDReader SDK version: **you can only enable document types that belong to the same `vector`** of supported document types for a single session. 182 | 183 | You can find full list of supported document types of Smart IDReader with their fields in [Documents Reference](./DOCUMENTS_REFERENCE.html). 184 | 185 | #### Enabling document types using wildcard expressions 186 | 187 | Since all documents in settings are disabled by default you need to enable some of them. 188 | In order to do so you may use `AddEnabledDocumentTypes(string)` and `SetEnabledDocumentTypes(vector)` (removes all and adds each string of the vector) methods of `SessionSettings`: 189 | 190 | ```cpp 191 | // settings->AddEnabledDocumentTypes("*"); 192 | settings->AddEnabledDocumentTypes("mrz.*"); 193 | // settings->AddEnabledDocumentTypes("card.*"); 194 | // settings->AddEnabledDocumentTypes("idmrz.*"); 195 | // settings->AddEnabledDocumentTypes("rus.passport.*"); 196 | // settings->AddEnabledDocumentTypes("rus.snils.*"); 197 | // settings->AddEnabledDocumentTypes("rus.sts.*"); 198 | // settings->AddEnabledDocumentTypes("rus.drvlic.*"); 199 | ``` 200 | 201 | You may also use `RemoveEnabledDocumentTypes(string)` method to remove already enabled document types. 202 | 203 | For convenience it's possible to use **wildcards** (using asterisk symbol) while enabling or disabling document types. When using document types related methods, each passed document type is matched against all supported document types. All matches in supported document types are added to the enabled document types list. For example, document type `rus.passport.internal` can be matched with `rus.*`, `*passport*` and of course a single asterisk `*`. 204 | 205 | In order to get actual enabled document types list after wildcard expression matching you can use: 206 | 207 | ```cpp 208 | const std::vector &enabled_doctypes = settings->GetEnabledDocumentTypes(); 209 | ``` 210 | 211 | As it was mentioned earlier, you can only enable document types that belong to the same `vector` of supported document types for a single session. 212 | If you do otherwise then informative exception will be thrown on `engine.SpawnSession(...)` call. 213 | 214 | It's always better to enable the minimum number of document types as possible if you know exactly what are you going to recognize because the system will spend less time deciding which document type out of all enabled ones has been presented to it. 215 | 216 | ## Session options 217 | 218 | Some configuration bundle options can be overriden in runtime using `se::smartid::SessionSettings` methods. You can obtain all option names and their values using: 219 | 220 | ```cpp 221 | const std::map &options = settings->GetOptions(); 222 | ``` 223 | 224 | You can change option values using `settings->SetOption(...)` method: 225 | 226 | ```cpp 227 | settings->SetOption("passport.extractTemplateImages", "true"); 228 | settings->SetOption("passport.extractFieldImages", "true"); 229 | ``` 230 | 231 | Option values are always `std::string` so if you want to pass an integer or boolean it should be converted to string first. It's done like that to avoid unwanted complexity with 'variant' classes and so on. 232 | 233 | #### Common options 234 | 235 | There is a special subset of options which have names in form `common.` which are general session options, for example: 236 | 237 | ```cpp 238 | settings->SetOption("common.sessionTimeout", "5.0"); // timeout in seconds 239 | ``` 240 | 241 | ## Result Reporter Callbacks 242 | 243 | Smart IDReader SDK supports optional callbacks during document analysis and recognition process before the `ProcessSnapshot(...)` or similar functions are finished. 244 | It allows the user to be more informed about the underlying recognition process and also helps creating more interactive GUI. 245 | 246 | To support callbacks you need to subclass `ResultReporterInterface` class and implement desirable callback methods: 247 | 248 | ```cpp 249 | class ConcreteResultReporter : public se::smartid::ResultReporterInterface { 250 | public: 251 | virtual void SnapshotRejected() override { } 252 | virtual void DocumentMatched(vector &match_results) override { } 253 | virtual void DocumentSegmented(const vector &segmentation_results) override { } 254 | virtual void SnapshotProcessed(const RecognitionResult &recog_result) override { } 255 | virtual void SessionEnded() override { } 256 | }; 257 | ``` 258 | 259 | Methods `DocumentMatched(...)` and `DocumentSegmented(...)` are especially useful for displaying document zones and fields bounds in GUI during live video stream recognition. 260 | 261 | We recommend using `override` keyword for C++11 because it greatly helps to avoid typos in function signatures. 262 | 263 | You also need to create an instance of `ConcreteResultReporter` somewhere in the code and pass it when you spawn the session: 264 | 265 | ```cpp 266 | ConcreteResultReporter reporter; 267 | 268 | unique_ptr session(engine.SpawnSession(*settings, &reporter)); 269 | ``` 270 | **Important!** Your `ResultReporterInterface` subclass instance must not be deleted while `RecognitionSession` is alive. We recommend to place them in the same scope. 271 | 272 | ## Java API 273 | 274 | Smart IDReader SDK has Java API which is automatically generated from C++ interface by SWIG tool. 275 | 276 | Java interface is the same as C++ except minor differences (e.g. STL containers wrappers), please see Java sample. 277 | 278 | There are several drawbacks related to Java memory management that you need to consider. 279 | 280 | #### Object deallocation 281 | 282 | Even though garbage collection is present and works, it's strongly advised to manually call `obj.delete()` functions for our API objects because they are wrappers to the heap-allocated memory and their heap size is unknown to the garbage collector. 283 | 284 | ```java 285 | RecognitionEngine engine = new RecognitionEngine(config_path); // or any other object 286 | 287 | // ... 288 | 289 | engine.delete(); // forces and immediately guarantees wrapped C++ object deallocation 290 | ``` 291 | 292 | This is important because from garbage collector's point of view these objects occupy several bytes of Java memory while their actual heap-allocated size may be up to several dozens of megabytes. GC doesn't know that and decides to keep them in memory – several bytes won't hurt, right? 293 | 294 | You don't want such objects to remain in your memory when they are no longer needed so call `obj.delete()` manually. 295 | 296 | #### Result Reporter Interface scope 297 | 298 | When using optional callbacks by subclassing `ResultReportingInterface` please make sure that its instance have the same scope as `RecognitionSession`. The reason for this is that our API does not own the pointer to the reporter instance which cause premature garbage collection resulting in crash: 299 | 300 | ```java 301 | // BAD: may cause premature garbage collection of reporter instance 302 | class MyDocumentRecognizer { 303 | private RecognitionEngine engine; 304 | private RecognitionSession session; 305 | 306 | private void InitializeSmartIdReader() { 307 | // ... 308 | session = engine.SpawnSession(settings, new MyResultReporter()); 309 | 310 | // reporter might be garbage collected there because session doesn't own it 311 | } 312 | } 313 | ``` 314 | 315 | ```java 316 | // GOOD: reporter have at least the scope of recognition session 317 | class MyDocumentRecognizer { 318 | private RecognitionEngine engine; 319 | private RecognitionSession session; 320 | private MyResultReporter reporter; // reporter has session's scope 321 | 322 | private void InitializeSmartIdReader() { 323 | // ... 324 | reporter = new MyResultReporter(); 325 | session = engine.SpawnSession(settings, reporter); 326 | } 327 | } 328 | ``` 329 | 330 | ## C API 331 | 332 | Smart IDReader SDK has C API for use cases where C++ is not possible. Please see C sample for details. 333 | 334 | #### C memory management 335 | 336 | Since there are no constructors and destructors in C we use Create/Destroy pairs of functions which are used to allocate and deallocate objects. 337 | 338 | #### Return codes and exception messages 339 | 340 | C does not have exceptions so every function returns `int` which must be `0` when function call was successful. Also, there is `CSmartIdErrorMessage *` passed to every function with error buffer containing propagated exception message if any exception has been thrown. 341 | -------------------------------------------------------------------------------- /doc/iOSIntegrationGuide.md: -------------------------------------------------------------------------------- 1 | ## Smart ID Reader SDK Integration Guide for iOS 2 | 3 | ### 1. Configuring Xcode project 4 | 5 | 1. Add `SESmartID` folder containing Objective-C source files to your project, select **Create groups** in the menu 6 | 2. Add `SESmartIDCore/lib` folder containing static library to your project, select **Create groups** in the menu 7 | 3. Add `SESmartIDCore/data-zip` folder to your project, select **Create folder references** in the menu 8 | 4. Add `SESmartIDCore/include` folder to the **Header Search Paths** in project settings 9 | 10 | ### 2. Sample code tutorial 11 | 12 | 1. Make your ViewController (```SESIDSampleViewController``` in sample project) conform to `````` and add an instance of ```SESIDViewController``` (for example, as a property). Note, that every `.m` file that includes `SESIDViewController.h` should be renamed to `.mm` to enable Objective-C++ compilation for this file. 13 | 14 | ```objectivec 15 | // SESIDSampleViewController.h 16 | 17 | #import "SESIDViewController.h" 18 | 19 | @interface SESIDSampleViewController : UIViewController 20 | 21 | @property (nonatomic, strong) SESIDViewController *smartIdViewController; 22 | 23 | // ... 24 | @end 25 | ``` 26 | 27 | Another way is to use *anonymous category* inside implementation file 28 | (details: [Apple Developer website](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210-CH6-SW3)). The advantage is that you'll need to rename only one file's extension to `.mm` 29 | 30 | ```objectivec++ 31 | // SESIDSampleViewController.h 32 | 33 | // left unchanged 34 | @interface SESIDSampleViewController : UIViewController 35 | // ... 36 | @end 37 | 38 | // SESIDSampleViewController.mm 39 | 40 | #import "SESIDViewController.h" 41 | 42 | @interface SESIDSampleViewController () 43 | 44 | @property SESIDViewController *smartIdViewController; 45 | 46 | @end 47 | ``` 48 | 49 | 2. Create and configure ```SESIDViewController``` instance 50 | 51 | ```objectivec++ 52 | // SESIDSampleViewController.mm 53 | 54 | // this might be called from viewDidLoad or similar methods, 55 | // depends on when do you want recognition core to be initialized. 56 | // could be done in the background thread 57 | - (void) initializeSmartIdViewController { 58 | // core configuration may take a while so it's better to be done 59 | // before displaying smart id view controller 60 | self.smartIdViewController = [[SESIDViewController alloc] init]; 61 | 62 | // assigning self as delegate to get smartIdViewControlerDidRecognizeResult called 63 | self.smartIdViewController.delegate = self; 64 | 65 | // configure optional visualization properties (they are NO by default) 66 | self.smartIdViewController.displayDocumentQuadrangle = YES; 67 | } 68 | ``` 69 | 70 | 3. Implement ```smartIdViewControllerDidRecognizeResult:``` method which will be called when ```SESIDViewController``` has successfully scanned a document and ```smartIdViewControllerDidCancel``` method which will be called when recognition has been cancelled by user 71 | 72 | ```objectivec++ 73 | // SESIDSampleViewController.mm 74 | 75 | - (void) smartIdViewControllerDidRecognizeResult:(const se::smartid::RecognitionResult &)result { 76 | // if result is not terminal we'd probably want to continue recognition until it becomes terminal 77 | // you can also check individual fields using result.GetStringField("field_name").IsAccepted() 78 | // in order to conditionally stop recognition when required fields are accepted 79 | if (!result.IsTerminal()) { 80 | return; 81 | } 82 | 83 | // dismiss Smart ID OCR view controller 84 | [self dismissViewControllerAnimated:YES completion:nil]; 85 | 86 | // use recognition result, see sample code for details 87 | // ... 88 | } 89 | 90 | - (void) smartIdViewControllerDidCancel { 91 | // dismiss Smart ID OCR view controller 92 | [self dismissViewControllerAnimated:YES completion:nil]; 93 | 94 | // ... 95 | } 96 | 97 | 98 | ``` 99 | 100 | 4. Present ```SESIDViewController``` modally when needed, set enabled document types before presenting 101 | 102 | ```objectivec++ 103 | // SESIDSampleViewController.mm 104 | 105 | - (void) showSmartIdViewController { 106 | if (!self.smartIdViewController) { 107 | [self initializeSmartIdViewController]; 108 | } 109 | 110 | // important! 111 | // setting enabled document types for this view controller 112 | // according to available document types for your delivery 113 | // these types will be passed to se::smartid::SessionSettings 114 | // with which se::smartid::RecognitionEngine::SpawnSession(...) is called 115 | // internally when Smart ID view controller is presented 116 | // you can specify a concrete document type or a wildcard expression (for convenience) 117 | // to enable or disable multiple types 118 | // by default no document types are enabled 119 | // if exception is thrown please read the exception message 120 | // see self.smartidViewController.supportedDocumentTypes, 121 | // se::smartid::SessionSettings and Smart IDReader documentation for further information 122 | [self.smartIdViewController removeEnabledDocumentTypesMask:"*"]; 123 | 124 | // [self.smartIdViewController addEnabledDocumentTypesMask:"*"]; 125 | // [self.smartIdViewController addEnabledDocumentTypesMask:"mrz.*"]; 126 | // [self.smartIdViewController addEnabledDocumentTypesMask:"card.*"]; 127 | [self.smartIdViewController addEnabledDocumentTypesMask:"rus.passport.*"]; 128 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.snils.*"]; 129 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.sts.*"]; 130 | // [self.smartIdViewController addEnabledDocumentTypesMask:"rus.drvlic.*"]; 131 | 132 | // if needed, set a timeout in seconds 133 | self.smartIdViewController.sessionTimeout = 5.0f; 134 | 135 | // presenting OCR view controller 136 | [self presentViewController:self.smartIdViewController 137 | animated:YES 138 | completion:nil]; 139 | 140 | // if you want to deinitialize view controller to save the memory, do this: 141 | // self.smartIdViewController = nil; 142 | } 143 | ``` 144 | -------------------------------------------------------------------------------- /doc/smartIdEngine.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/90fdd5ff785b89be9f629230351f7ba906ccfbb5/doc/smartIdEngine.pdf --------------------------------------------------------------------------------