├── .gitignore
├── SESmartIDCore
├── data-zip
│ └── bundle_mock_smart_idreader.zip
├── lib
│ └── libsmartid-universal.a
└── include
│ └── smartIdEngine
│ ├── smartid_common.h
│ ├── smartid_engine.h
│ └── smartid_result.h
├── doc
├── smartIdEngine.pdf
├── README.md
├── iOSIntegrationGuide.md
└── SmartIDReaderSDK.md
├── SESmartIDSample
├── Default-568h@2x.png
├── Info.plist
├── SESIDSampleAppDelegate.h
├── main.m
├── SESIDSampleViewController.h
├── SESIDSampleAppDelegate.m
└── SESIDSampleViewController.mm
├── SESmartIDSample.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── SESmartID
├── SESIDRoiOverlayView.h
├── SESIDQuadrangleView.h
├── SESIDCameraManager.h
├── SESIDRecognitionCore.h
├── SESIDQuadrangleView.mm
├── SESIDViewController.h
├── SESIDCameraManager.m
├── SESIDRoiOverlayView.m
├── SESIDRecognitionCore.mm
└── SESIDViewController.mm
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata/
2 | .DS_Store
3 |
--------------------------------------------------------------------------------
/SESmartIDCore/data-zip/bundle_mock_smart_idreader.zip:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/doc/smartIdEngine.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/HEAD/doc/smartIdEngine.pdf
--------------------------------------------------------------------------------
/SESmartIDSample/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/HEAD/SESmartIDSample/Default-568h@2x.png
--------------------------------------------------------------------------------
/SESmartIDCore/lib/libsmartid-universal.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SmartEngines/SmartIDReader-iOS-SDK/HEAD/SESmartIDCore/lib/libsmartid-universal.a
--------------------------------------------------------------------------------
/SESmartIDSample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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/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/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/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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