Demos and Sample Code







Warning
With Anyline 4 we have two types of json files. One of them contains also the scan plugin specified in it (e.g. “plugin”: {“id”: “VIN_ID”, …}). With this, all the parameters specific to the scan plugin (e.g. scanMode, charWhitelist) should not be specified in the code anymore, but in the json.
If you explicitly load the scan plugin in your code and/or scan view plugin configuration, please make sure that your json config file does not contain the plugin element.
Meter Plugin Analog/Digital Automatic (Documentation)
{
"camera":{
"captureResolution" : "720p"
},
"flash" : {
"mode" : "manual",
"alignment" : "bottom"
},
"viewPlugin" : {
"plugin" : {
"id" : "METER_ID",
"meterPlugin": {
"scanMode": "AUTO_ANALOG_DIGITAL_METER"
}
},
"cutoutConfig" : {
"style" : "rect",
"alignment" : "top_half",
"strokeWidth" : 2,
"strokeColor" : "FFFFFF",
"cornerRadius" : 4,
"outerColor" : "000000",
"outerAlpha" : 0.5,
"feedbackStrokeColor" : "0099FF"
},
"scanFeedback" : {
"style" : "CONTOUR_RECT",
"strokeColor" : "0099FF",
"fillColor" : "220099FF",
"blinkOnResult": true,
"beepOnResult": true,
"vibrateOnResult": true
},
"cancelOnResult" : true
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.meter.MeterScanResult;
import io.anyline.plugin.meter.MeterScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanAutoAnalogDigitalMeter extends Activity {
private ScanView scanView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anyline_test);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
// initialize Anyline with a Listener that is called if a result is found
try {
scanView.init("energy_auto_analog_digital_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
MeterScanViewPlugin scanViewPlugin = (MeterScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<MeterScanResult>() {
@Override
public void onResult(MeterScanResult result) {
Toast.makeText(getApplicationContext(), result.getResult(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | #import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALAutoAnalogDigitalMeterScanViewController.h"
#import <Anyline/Anyline.h>
#import "ALAppDemoLicenses.h"
#import "ALResultEntry.h"
#import "ALResultViewController.h"
// This is the license key for the examples project used to set up Aynline below
NSString * const kAutoAnalogDigitalMeterScanLicenseKey = kDemoAppLicenseKey;
static const NSInteger padding = 7;
// The controller has to conform to <AnylineEnergyModuleDelegate> to be able to receive results
@interface ALAutoAnalogDigitalMeterScanViewController ()<ALMeterScanPluginDelegate, AnylineNativeBarcodeDelegate>
// The Anyline plugins used to scan
@property (nonatomic, strong) ALMeterScanViewPlugin *meterScanViewPlugin;
@property (nonatomic, strong) ALMeterScanPlugin *meterScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
//Native barcode scanning properties
@property (nonatomic, strong) NSString *barcodeResult;
@property (nonatomic, strong) UIView *enableBarcodeView;
@property (nonatomic, strong) UISwitch *enableBarcodeSwitch;
@property (nonatomic, strong) UILabel *enableBarcodeLabel;
@end
@implementation ALAutoAnalogDigitalMeterScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"Analog/Digital Meter";
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kDemoAppLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
//Add Meter Scan Plugin (Scan Process)
NSError *error = nil;
self.meterScanPlugin = [[ALMeterScanPlugin alloc] initWithPluginID:@"ENERGY" delegate:self error:&error];
NSAssert(self.meterScanPlugin, @"Setup Error: %@", error.debugDescription);
//Add Meter Scan View Plugin (Scan UI)
self.meterScanViewPlugin = [[ALMeterScanViewPlugin alloc] initWithScanPlugin:self.meterScanPlugin];
//Set ScanMode to ALAutoAnalogDigitalMeter
BOOL success = [self.meterScanPlugin setScanMode:ALAutoAnalogDigitalMeter error:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
[[[UIAlertView alloc] initWithTitle:@"Set ScanMode Error"
message:error.debugDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
//Add ScanView (Camera and Flashbutton)
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.meterScanViewPlugin];
[self.view addSubview:self.scanView];
[self.scanView startCamera];
BOOL enableReporting = [NSUserDefaults AL_reportingEnabled];
[self.meterScanPlugin enableReporting:enableReporting];
self.meterScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO;
//After setup is complete we add the module to the view of this view controller
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView}]];
id topGuide = self.topLayoutGuide;
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-0-[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView, @"topGuide" : topGuide}]];
self.controllerType = ALScanHistoryElectricMeter;
self.barcodeResult = @"";
[self.view sendSubviewToBack:self.scanView];
[self.scanView addSubview:[self createBarcoeSwitchView]];
[self.scanView bringSubviewToFront:self.enableBarcodeView];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
/*
This is the place where we tell Anyline to start receiving and displaying images from the camera.
Success/error tells us if everything went fine.
*/
NSError *error = nil;
BOOL success = [self.meterScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
[[[UIAlertView alloc] initWithTitle:@"Start Scanning Error"
message:error.debugDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self updateLayoutBarcodeSwitchView];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.meterScanViewPlugin stopAndReturnError:nil];
}
#pragma mark - IBAction methods
- (IBAction)toggleBarcodeScanning:(id)sender {
if (self.scanView.captureDeviceManager.barcodeDelegates.count > 0) {
self.enableBarcodeSwitch.on = false;
[self.scanView.captureDeviceManager removeBarcodeDelegate:self];
//reset found barcode
self.barcodeResult = @"";
} else {
self.enableBarcodeSwitch.on = true;
[self.scanView.captureDeviceManager addBarcodeDelegate:self error:nil];
}
}
#pragma mark - Barcode View layouting
- (UIView *)createBarcoeSwitchView {
//Add UISwitch for toggling barcode scanning
self.enableBarcodeView = [[UIView alloc] init];
self.enableBarcodeView.frame = CGRectMake(100, 100, 150, 50);
self.enableBarcodeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
self.enableBarcodeLabel.text = @"Barcode Detection";
UIFont *font = [UIFont systemFontOfSize:14 weight:UIFontWeightThin];
self.enableBarcodeLabel.font = font;
self.enableBarcodeLabel.numberOfLines = 0;
self.enableBarcodeLabel.textColor = [UIColor whiteColor];
[self.enableBarcodeLabel sizeToFit];
self.enableBarcodeSwitch = [[UISwitch alloc] init];
[self.enableBarcodeSwitch setOn:false];
self.enableBarcodeSwitch.onTintColor = [UIColor whiteColor];
[self.enableBarcodeSwitch setOnTintColor:[UIColor colorWithRed:0.0/255.0 green:153.0/255.0 blue:255.0/255.0 alpha:1.0]];
[self.enableBarcodeSwitch addTarget:self action:@selector(toggleBarcodeScanning:) forControlEvents:UIControlEventValueChanged];
[self.enableBarcodeView addSubview:self.enableBarcodeLabel];
[self.enableBarcodeView addSubview:self.enableBarcodeSwitch];
return self.enableBarcodeView;
}
- (void)updateLayoutBarcodeSwitchView {
self.enableBarcodeLabel.center = CGPointMake(self.enableBarcodeLabel.frame.size.width/2,
self.enableBarcodeView.frame.size.height/2);
self.enableBarcodeSwitch.center = CGPointMake(self.enableBarcodeLabel.frame.size.width + self.enableBarcodeSwitch.frame.size.width/2 + padding,
self.enableBarcodeView.frame.size.height/2);
CGFloat width = self.enableBarcodeSwitch.frame.size.width + padding + self.enableBarcodeLabel.frame.size.width;
self.enableBarcodeView.frame = CGRectMake(self.scanView.frame.size.width-width-15,
self.scanView.frame.size.height-self.enableBarcodeView.frame.size.height-55,
width,
50);
}
#pragma mark - ALMeterScanPluginDelegate methods
/*
The main delegate method Anyline uses to report its scanned codes
*/
- (void)anylineMeterScanPlugin:(ALMeterScanPlugin *)anylineMeterScanPlugin
didFindResult:(ALMeterResult *)scanResult {
[self anylineDidFindResult:scanResult.result barcodeResult:self.barcodeResult image:(UIImage*)scanResult.image scanPlugin:anylineMeterScanPlugin viewPlugin:self.meterScanViewPlugin completion:^{
//Display the result
NSMutableArray <ALResultEntry*> *resultData = [[NSMutableArray alloc] init];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Meter Reading" value:scanResult.result]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Barcode" value:self.barcodeResult]];
ALResultViewController *vc = [[ALResultViewController alloc] initWithResultData:resultData image:scanResult.image];
[self.navigationController pushViewController:vc animated:YES];
}];
//reset found barcodes
self.barcodeResult = @"";
}
#pragma mark - AnylineNativeBarcodeDelegate methods
/*
An additional delegate which will add all found, and unique, barcodes to a Dictionary simultaneously.
*/
- (void)anylineCaptureDeviceManager:(ALCaptureDeviceManager *)captureDeviceManager didFindBarcodeResult:(NSString *)scanResult type:(NSString *)barcodeType {
dispatch_async(dispatch_get_main_queue(), ^{
if ([scanResult length] > 0 && ![self.barcodeResult isEqualToString:scanResult]) {
self.barcodeResult = scanResult;
}
});
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Meter;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<MeterScanResult>, IPhotoCaptureListener
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/energy_config_analog_digital.json");
var scanViewPlugin = AnylineScanView?.ScanViewPlugin as MeterScanViewPlugin;
if(scanViewPlugin != null)
{
// attach the result listener to the ScanViewPlugin to receive scanning results
scanViewPlugin.AddScanResultListener(this);
scanViewPlugin.PhotoCaptureListener = this;
scanViewPlugin.PhotoCaptureTarget = PhotoCaptureTarget.File;
}
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<MeterScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
public void OnPhotoCaptured(AnylineImage anylineImage)
{
// do something with the image
}
public async void OnPhotoToFile(StorageFile file)
{
BitmapImage bitmapImage = new BitmapImage();
FileRandomAccessStream stream = (FileRandomAccessStream)await file.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
// do something with the bitmapImage
}
}
}
|
Dial Meter (Alpha) (Documentation)
{
"camera": {
"captureResolution": "720p"
},
"flash": {
"mode": "manual",
"alignment": "top_left"
},
"viewPlugin": {
"plugin": {
"id": "DIAL_METER",
"meterPlugin": {
"scanMode": "DIAL_METER"
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "90%",
"maxHeightPercent": "90%",
"alignment": "top_half",
"ratioFromSize": {
"width": 125,
"height": 85
},
"offset": {
"x": 0,
"y": 15
},
"cropPadding": {
"x": 0,
"y": 0
},
"cropOffset": {
"x": 0,
"y": 0
},
"strokeWidth": 2,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"style": "CONTOUR_RECT",
"strokeColor": "0099FF",
"fillColor": "220099FF",
"blinkOnResult": true,
"beepOnResult": true,
"vibrateOnResult": true
},
"cancelOnResult": true
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.Nullable;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.meter.MeterScanResult;
import io.anyline.plugin.meter.MeterScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanDialMeter extends Activity {
private ScanView scanView;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anyline_test);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
// initialize Anyline with a Listener that is called if a result is found
try {
scanView.init("energy_dial_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
MeterScanViewPlugin scanViewPlugin = (MeterScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<MeterScanResult>() {
@Override
public void onResult(MeterScanResult result) {
Toast.makeText(getApplicationContext(), result.getResult(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
}
}
|
ID Plugin MRZ (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | {
"camera": {
"captureResolution": "720",
"defaultCamera": "BACK"
},
"flash": {
"mode": "manual",
"alignment": "bottom_right"
},
"viewPlugin": {
"plugin": {
"id": "ID_PLUGIN",
"idPlugin": {
"mrzConfig": {
"strictMode" : false,
"cropAndTransformID" : false,
"mrzFieldScanOptions": {
"vizAddress": "mandatory"
},
"mrzMinFieldConfidences": {
"surname": 70,
"givenNames":80,
"vizAddress":30
},
"minConfidence": 50
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "99%",
"maxHeightPercent": "100%",
"alignment": "center",
"ratioFromSize": {
"width": 560,
"height": 354
},
"strokeWidth": 2,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"fillColor": "220099FF",
"style": "CONTOUR_POINT",
"strokeColor": "0099FF",
"strokeWidth": 2,
"blinkOnResult": true,
"beepOnResult": true,
"vibrateOnResult": true
},
"cancelOnResult": true,
"delayStartScanTime" : 1000
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | package at.nineyards.anyline.test;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResult;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.id.ID;
import io.anyline.plugin.id.IdScanViewPlugin;
import io.anyline.plugin.id.MrzIdentification;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanMRZActivity extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anyline4_test);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
//init the scan view
scanView.init("mrz_view_config.json");
IdScanViewPlugin scanViewPlugin = (IdScanViewPlugin) scanView.getScanViewPlugin();
scanView.setScanViewPlugin(scanViewPlugin);
// add the result listener
scanViewPlugin.addScanResultListener(new ScanResultListener<ScanResult<ID>>() {
@Override
public void onResult(ScanResult<ID> result) {
MrzIdentification identification = (MrzIdentification) result.getResult();
Toast.makeText(getApplicationContext(), identification.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | #import "ALMRZScanViewController.h"
#import "ALIdentificationView.h"
#import <Anyline/Anyline.h>
#import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALAppDemoLicenses.h"
#import "ALResultViewController.h"
// This is the license key for the examples project used to set up Aynline below
NSString * const kMRZLicenseKey = kDemoAppLicenseKey;
// The controller has to conform to <AnylineMRZModuleDelegate> to be able to receive results
@interface ALMRZScanViewController ()<ALIDPluginDelegate, ALInfoDelegate>
// The Anyline module used to scan machine readable zones
@property (nonatomic, strong) ALIDScanViewPlugin *mrzScanViewPlugin;
@property (nonatomic, strong) ALIDScanPlugin *mrzScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALMRZScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"MRZ";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kMRZLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
ALMRZConfig *mrzConfig = [[ALMRZConfig alloc] init];
NSError *error = nil;
self.mrzScanPlugin = [[ALIDScanPlugin alloc] initWithPluginID:@"ModuleID" delegate:self idConfig:mrzConfig error:&error];
NSAssert(self.mrzScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.mrzScanPlugin addInfoDelegate:self];
self.mrzScanViewPlugin = [[ALIDScanViewPlugin alloc] initWithScanPlugin:self.mrzScanPlugin];
NSAssert(self.mrzScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.mrzScanViewPlugin];
self.scanView.flashButtonConfig.flashAlignment = ALFlashAlignmentTopLeft;
self.mrzScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO;
self.controllerType = ALScanHistoryMrz;
// After setup is complete we add the module to the view of this view controller
[self.view addSubview:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self.view sendSubviewToBack:self.scanView];
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView}]];
id topGuide = self.topLayoutGuide;
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-0-[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView, @"topGuide" : topGuide}]];
[self startListeningForMotion];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
//Update Position of Warning Indicator
[self updateWarningPosition:
self.mrzScanViewPlugin.cutoutRect.origin.y +
self.mrzScanViewPlugin.cutoutRect.size.height +
self.mrzScanViewPlugin.frame.origin.y +
120];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.mrzScanViewPlugin stopAndReturnError:nil];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found scanning will stop automatically (you can change this behaviour
with cancelOnResult:). When the user dismisses self.identificationView this
method will get called again.
*/
- (void)startAnyline {
NSError *error;
BOOL success = [self.mrzScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
[[[UIAlertView alloc] initWithTitle:@"Start Scanning Error"
message:error.debugDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
self.startTime = CACurrentMediaTime();
}
#pragma mark -- AnylineMRZModuleDelegate
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin didFindResult:(ALIDResult *)scanResult {
[self.mrzScanViewPlugin stopAndReturnError:nil];
NSMutableString * result = [NSMutableString string];
[result appendString:[NSString stringWithFormat:@"Document Type: %@\n", [scanResult.result documentType]]];
[result appendString:[NSString stringWithFormat:@"Document Number: %@\n", [scanResult.result documentNumber]]];
[result appendString:[NSString stringWithFormat:@"Surnames: %@\n", [scanResult.result surNames]]];
[result appendString:[NSString stringWithFormat:@"Given Names: %@\n", [scanResult.result givenNames]]];
[result appendString:[NSString stringWithFormat:@"Issuing Country Code: %@\n", [scanResult.result issuingCountryCode]]];
[result appendString:[NSString stringWithFormat:@"Nationality Country Code: %@\n", [scanResult.result nationalityCountryCode]]];
[result appendString:[NSString stringWithFormat:@"Day Of Birth: %@\n", [scanResult.result dayOfBirth]]];
[result appendString:[NSString stringWithFormat:@"Expiration Date: %@\n", [scanResult.result expirationDate]]];
[result appendString:[NSString stringWithFormat:@"Sex: %@\n", [scanResult.result sex]]];
[result appendString:[NSString stringWithFormat:@"Check Digit Number: %@\n", [scanResult.result checkdigitNumber]]];
[result appendString:[NSString stringWithFormat:@"Check Digit Expiration Date: %@\n", [scanResult.result checkdigitExpirationDate]]];
[result appendString:[NSString stringWithFormat:@"Check Digit Day Of Birth: %@\n", [scanResult.result checkdigitDayOfBirth]]];
[result appendString:[NSString stringWithFormat:@"Check Digit Final: %@\n", [scanResult.result checkdigitFinal]]];
[result appendString:[NSString stringWithFormat:@"Personal Number: %@\n", [scanResult.result personalNumber]]];
[result appendString:[NSString stringWithFormat:@"Check Digit Personal Number: %@\n", [scanResult.result checkDigitPersonalNumber]]];
[super anylineDidFindResult:result barcodeResult:@"" image:scanResult.image scanPlugin:anylineIDScanPlugin viewPlugin:self.mrzScanViewPlugin completion:^{
NSMutableArray <ALResultEntry*> *resultData = [[NSMutableArray alloc] init];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Given Name" value:[scanResult.result givenNames]]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Surname" value:[scanResult.result surNames]]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Sex" value:[scanResult.result sex]]];
[resultData addObject:[self resultEntryWithDate:[scanResult.result dayOfBirthDateObject] dateString:[scanResult.result dayOfBirth] title:@"Date of Birth"]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Type" value:[scanResult.result documentType]]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Document Number" value:[scanResult.result documentNumber]]];
[resultData addObject:[self resultEntryWithDate:[scanResult.result expirationDateObject] dateString:[((ALMRZIdentification *)scanResult.result) expirationDate] title:@"Expiration Date"]];
[resultData addObject:[[ALResultEntry alloc] initWithTitle:@"Nationality" value:[scanResult.result nationalityCountryCode]]];
ALResultViewController *vc = [[ALResultViewController alloc] initWithResultData:resultData image:scanResult.image optionalImageTitle:@"Detected Face Image" optionalImage:[scanResult.result faceImage]];
[self.navigationController pushViewController:vc animated:YES];
}];
}
- (ALResultEntry *)resultEntryWithDate:(NSDate *)date dateString:(NSString *)dateString title:(NSString *)title {
if (![self checkDateIfAvailable:date dateString:dateString]) {
return [[ALResultEntry alloc] initWithTitle:title value:nil];
}
NSString *value = [self formatDate:date];
return [[ALResultEntry alloc] initWithTitle:title value:value isAvailable:(date)];
}
- (BOOL)checkDateIfAvailable:(NSDate *)date dateString:(NSString *)dateString {
if (!date && dateString.length == 0) {
return NO;
}
return YES;
}
- (NSString *)formatDate:(NSDate *)date {
if (!date) {
return @"Date not valid";
}
return [NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterNoStyle];
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.ID;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<ScanResult<ID>>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as IDScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<ID> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
var mrzIdentification = result.Result as MrzIdentification;
Debug.WriteLine($"(APP) Given Names result: {mrzIdentification.GivenNames}");
}
}
}
|
ID Plugin Universal ID (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | {
"camera" : {
"captureResolution" : "1080p",
"zoomGesture": true
},
"flash" : {
"mode": "manual",
"alignment": "top_left"
},
"viewPlugin" : {
"plugin":{
"id":"ID",
"idPlugin": {
"universalIdConfig": {
"allowedLayouts": {
"mrz": [],
"drivingLicense": [],
"idFront": [],
"insuranceCard" : []
},
"drivingLicense": {
"surname": {"scanOption": 0, "minConfidence": 40},
"givenNames": {"scanOption": 0, "minConfidence": 40},
"dateOfBirth": {"scanOption": 0, "minConfidence": 50},
"placeOfBirth": {"scanOption": 1, "minConfidence": 50},
"dateOfIssue": {"scanOption": 0, "minConfidence": 50},
"dateOfExpiry": {"scanOption": 1, "minConfidence": 50},
"authority": {"scanOption": 1, "minConfidence": 30},
"documentNumber": {"scanOption": 0, "minConfidence": 40},
"categories": {"scanOption": 1, "minConfidence": 30},
"address": {"scanOption": 1}
},
"idFront": {
"surname": {"scanOption": 0, "minConfidence": 60},
"givenNames": {"scanOption": 0, "minConfidence": 60},
"dateOfBirth": {"scanOption": 0, "minConfidence": 60},
"placeOfBirth": {"scanOption": 1, "minConfidence": 60},
"dateOfExpiry": {"scanOption": 1, "minConfidence": 60},
"cardAccessNumber": {"scanOption": 1, "minConfidence": 60},
"documentNumber": {"scanOption": 0, "minConfidence": 60},
"nationality": {"scanOption": 1, "minConfidence": 60}
},
"insuranceCard": {
"nationality": {"scanOption": 0, "minConfidence": 50},
"surname": {"scanOption": 0, "minConfidence": 50},
"givenNames": {"scanOption": 0, "minConfidence": 50},
"dateOfBirth": {"scanOption": 0, "minConfidence": 50},
"personalNumber": {"scanOption": 0, "minConfidence": 50},
"authority": {"scanOption": 0, "minConfidence": 50},
"documentNumber": {"scanOption": 0, "minConfidence": 50},
"dateOfExpiry": {"scanOption": 0, "minConfidence": 50}
}
}
}
},
"cutoutConfig" : {
"style": "animated_rect",
"maxWidthPercent": "90%",
"maxHeightPercent": "90%",
"alignment": "center",
"strokeWidth": 3,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"ratioFromSize" : {
"width": 50,
"height": 31
},
"cropPadding": {
"x": -50,
"y": -50
},
"cropOffset": {
"x": 0,
"y": 0
},
"feedbackStrokeColor": "0099FF"
},
"scanFeedback" : {
"style": "CONTOUR_RECT",
"visualFeedbackRedrawTimeout": 100,
"strokeColor": "0099FF",
"fillColor" : "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"strokeWidth": 3
},
"cancelOnResult" : true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | public class ScanUniversalIdActivity extends AppCompatActivity implements ScanRunSkippedListener {
ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_universal_id);
init();
}
void init(){
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
scanView.init("myConfig.json");
IdScanViewPlugin idScanViewPlugin = (IdScanViewPlugin) scanView.getScanViewPlugin();
scanView.getScanViewPlugin().addScanRunSkippedListener(this);
idScanViewPlugin.addScanResultListener((ScanResultListener<ScanResult<ID>>) idScanResult -> {
Identification identification = (Identification) idScanResult.getResult();
HashMap<String, String> data = (HashMap<String, String>) identification.getResultData();
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onStop() {
super.onStop();
scanView.stop();
}
@Override
public void onRunSkipped(ScanRunSkippedReason reason) {
if(reason.getCode() == 5555){
Toast.makeText(this, (reason.getText()), Toast.LENGTH_SHORT).show();
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | //
// ALUniversalIDViewController.m
// AnylineExamples
//
// Created by Aldrich Co on 08.12.21.
//
#import "ALUniversalIDViewController.h"
// This is the license key for the examples project used to set up Anyline below
NSString * const kUniversalIDLicenseKey = @"ADD YOUR LICENSE KEY";
@interface ALUniversalIDScanViewControllerFrontAndBack ()<ALIDPluginDelegate>
@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPlugin;
@property (nonatomic, strong) ALIDScanPlugin *scanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALUniversalIDViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
// Initialise the Anyline License
NSError *licenseError = nil;
[AnylineSDK setupWithLicenseKey:kUniversalIDLicenseKey error:&licenseError];
if (licenseError) {
// Handle the error. You would be unable to use the scan view and scan plugin
// in the event of an error, so it may be a good idea to make an early return.
}
NSError *error = nil;
NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"universal_id_config"
ofType:@"json"];
NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath];
NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile
options:NSJSONReadingMutableContainers
error:&error];
// Initialise the scan view plugin using the JSON configuration file and setting oneself
// as its ALIDPluginDelegate
self.scanViewPlugin = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin scanViewPluginForConfigDict:configDict delegate:self error:&error];
NSAssert(self.scanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanPlugin = self.scanViewPlugin.idScanPlugin;
// Implement ALScanViewPluginDelegate for its `anylineScanViewPlugin:updatedCutout:` method
// [self.scanViewPlugin addScanViewPluginDelegate:self];
// Implement ALInfoDelegate if interested in meta-variables reported while scanning
// [self.scanPlugin addInfoDelegate:self];
// Set the scanView's frame to fill the whole screen
CGRect frame = [self scanViewFrame];
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scanViewPlugin];
// You can still configure the scan view config until the plugin is started;
// here we set the flash button position within the scan view
self.scanView.flashButtonConfig.flashAlignment = ALFlashAlignmentTopLeft;
// After setup is complete we add the scanView to the view of this view controller
[self.view addSubview:self.scanView];
[self.scanView startCamera];
}
/*
Start the scanning process once the view hierarchy has appeared onscreen.
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.scanViewPlugin stopAndReturnError:nil];
[super viewWillDisappear:animated];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found, scanning will stop automatically (you can change this behaviour
with cancelOnResult:).
*/
- (void)startAnyline {
NSError *error = nil;
[self.scanViewPlugin startAndReturnError:&error];
// Handle if error is not null here
}
// MARK: - ALIDPluginDelegate
/*
This is the main delegate method Anyline uses to report its results.
*/
- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin
didFindResult:(ALIDResult *)scanResult {
ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result;
NSArray<NSString *> *fieldNames = identification.fieldNames;
ALLayoutDefinition *layoutDefinition = identification.layoutDefinition;
ALUniversalIDFieldConfidences *fieldConfidences = identification.fieldConfidences;
UIImage *faceImage = identification.faceImage;
// Handle your result here
// ...
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Barcode;
using Anyline.SDK.Plugins.ID;
using Anyline.SDK.Plugins.LicensePlate;
using Anyline.SDK.Plugins.Meter;
using Anyline.SDK.Plugins.OCR;
using Anyline.SDK.Plugins.ViewPlugins;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Windows.Foundation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using Anyline.SDK.Views;
using Anyline.SDK.Plugins.ID;
namespace Anyline_Windows_UWP_Examples
{
public sealed partial class ScanViewPage : Page,
IScanResultListener<ScanResult<ID>>
{
private ScanView anylineScanView;
private IViewPluginBase scanViewPlugin;
public ScanViewPage()
{
// We don't want to keep multiple instances of the scan views that we're navigating to.
NavigationCacheMode = NavigationCacheMode.Required;
((Frame)Window.Current.Content).CacheSize = 0;
this.InitializeComponent();
anylineScanView = AnylineScanView;
}
private void CameraView_CameraOpened(object sender, Size args)
{
Debug.WriteLine($"(APP) Camera Opened: {args.Width}x{args.Height}");
try
{
anylineScanView?.StartScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraClosed(object sender, bool success)
{
Debug.WriteLine($"(APP) Camera Closed: {success}");
try
{
anylineScanView?.StopScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraError(object sender, Exception exception)
{
Debug.WriteLine($"(APP) Camera Error: {exception.Message}");
}
// important because the UWP camera stream automatically shuts down when a window is minimized
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (args.Visible == false)
{
if (anylineScanView != null)
{
await anylineScanView.StopCameraAsync();
}
}
if (args.Visible == true)
{
anylineScanView?.StartCamera();
}
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
await anylineScanView.StopCameraAsync();
anylineScanView.Dispose();
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (anylineScanView == null) return;
// register events
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
anylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
anylineScanView.CameraView.CameraError += CameraView_CameraError;
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
Window.Current.VisibilityChanged += Current_VisibilityChanged;
}
string jsonConfig = (e.Parameter as ExamplePlugin).JSONConfigFile;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// the correct plugin is loaded according to the .json config file informed
scanViewPlugin = anylineScanView.ScanViewPlugin;
scanViewPlugin.AddScanResultListener(this);
anylineScanView?.StartCamera();
}
public void OnResult(ScanResult<ID> result)
{
if (result.Result is Identification id) {
// get layout definition here:
var layoutDefinition = id.LayoutDefinition;
// iterate through values of the id, because it is enumerable
foreach(var parameter in id) {
Debug.WriteLine($"Parameter name: {parameter.Key}, value: {parameter.Value}, Confidence: {id.FieldConfidences[parameter.Key]}");
}
}
}
}
}
|
Japanese Landing Permission (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | {
"camera": {
"captureResolution": "1080p",
"zoomGesture": true
},
"flash": {
"mode": "manual",
"alignment": "bottom_right"
},
"viewPlugin" : {
"plugin": {
"id": "ID",
"idPlugin": {
"japaneseLandingPermissionConfig": {
"miscellaneous": {
"dateOfIssue": {"scanOption": 0,"minConfidence": 35},
"dateOfExpiry": {"scanOption": 0,"minConfidence": 35},
"status": {"scanOption": 1,"minConfidence": 35},
"duration": {"scanOption": 0,"minConfidence": 35},
"airport": {"scanOption": 0,"minConfidence": 35}
}
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "70%",
"maxHeightPercent": "70%",
"alignment": "center",
"strokeWidth": 2,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"ratioFromSize": {
"width": 440,
"height": 615
},
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"style": "RECT",
"visualFeedbackRedrawTimeout": 100,
"strokeColor": "0099FF",
"fillColor": "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"strokeWidth": 2
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | public class ScanUniversalIdActivity extends AppCompatActivity implements ScanRunSkippedListener {
ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_universal_id);
init();
}
void init(){
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
scanView.init("myConfig.json");
IdScanViewPlugin idScanViewPlugin = (IdScanViewPlugin) scanView.getScanViewPlugin();
scanView.getScanViewPlugin().addScanRunSkippedListener(this);
idScanViewPlugin.addScanResultListener((ScanResultListener<ScanResult<ID>>) idScanResult -> {
Identification identification = (Identification) idScanResult.getResult();
HashMap<String, String> data = (HashMap<String, String>) identification.getResultData();
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onStop() {
super.onStop();
scanView.stop();
}
@Override
public void onRunSkipped(ScanRunSkippedReason reason) {
if(reason.getCode() == 5555){
Toast.makeText(this, (reason.getText()), Toast.LENGTH_SHORT).show();
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | //
// ALUniversalIDViewController.m
// AnylineExamples
//
// Created by Aldrich Co on 08.12.21.
//
#import "ALUniversalIDViewController.h"
// This is the license key for the examples project used to set up Anyline below
NSString * const kUniversalIDLicenseKey = @"ADD YOUR LICENSE KEY";
@interface ALUniversalIDScanViewControllerFrontAndBack ()<ALIDPluginDelegate>
@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPlugin;
@property (nonatomic, strong) ALIDScanPlugin *scanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALUniversalIDViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
// Initialise the Anyline License
NSError *licenseError = nil;
[AnylineSDK setupWithLicenseKey:kUniversalIDLicenseKey error:&licenseError];
if (licenseError) {
// Handle the error. You would be unable to use the scan view and scan plugin
// in the event of an error, so it may be a good idea to make an early return.
}
NSError *error = nil;
NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"universal_id_config"
ofType:@"json"];
NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath];
NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile
options:NSJSONReadingMutableContainers
error:&error];
// Initialise the scan view plugin using the JSON configuration file and setting oneself
// as its ALIDPluginDelegate
self.scanViewPlugin = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin scanViewPluginForConfigDict:configDict delegate:self error:&error];
NSAssert(self.scanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanPlugin = self.scanViewPlugin.idScanPlugin;
// Implement ALScanViewPluginDelegate for its `anylineScanViewPlugin:updatedCutout:` method
// [self.scanViewPlugin addScanViewPluginDelegate:self];
// Implement ALInfoDelegate if interested in meta-variables reported while scanning
// [self.scanPlugin addInfoDelegate:self];
// Set the scanView's frame to fill the whole screen
CGRect frame = [self scanViewFrame];
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scanViewPlugin];
// You can still configure the scan view config until the plugin is started;
// here we set the flash button position within the scan view
self.scanView.flashButtonConfig.flashAlignment = ALFlashAlignmentTopLeft;
// After setup is complete we add the scanView to the view of this view controller
[self.view addSubview:self.scanView];
[self.scanView startCamera];
}
/*
Start the scanning process once the view hierarchy has appeared onscreen.
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.scanViewPlugin stopAndReturnError:nil];
[super viewWillDisappear:animated];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found, scanning will stop automatically (you can change this behaviour
with cancelOnResult:).
*/
- (void)startAnyline {
NSError *error = nil;
[self.scanViewPlugin startAndReturnError:&error];
// Handle if error is not null here
}
// MARK: - ALIDPluginDelegate
/*
This is the main delegate method Anyline uses to report its results.
*/
- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin
didFindResult:(ALIDResult *)scanResult {
ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result;
NSArray<NSString *> *fieldNames = identification.fieldNames;
ALLayoutDefinition *layoutDefinition = identification.layoutDefinition;
ALUniversalIDFieldConfidences *fieldConfidences = identification.fieldConfidences;
UIImage *faceImage = identification.faceImage;
// Handle your result here
// ...
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Barcode;
using Anyline.SDK.Plugins.ID;
using Anyline.SDK.Plugins.LicensePlate;
using Anyline.SDK.Plugins.Meter;
using Anyline.SDK.Plugins.OCR;
using Anyline.SDK.Plugins.ViewPlugins;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Windows.Foundation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using Anyline.SDK.Views;
using Anyline.SDK.Plugins.ID;
namespace Anyline_Windows_UWP_Examples
{
public sealed partial class ScanViewPage : Page,
IScanResultListener<ScanResult<ID>>
{
private ScanView anylineScanView;
private IViewPluginBase scanViewPlugin;
public ScanViewPage()
{
// We don't want to keep multiple instances of the scan views that we're navigating to.
NavigationCacheMode = NavigationCacheMode.Required;
((Frame)Window.Current.Content).CacheSize = 0;
this.InitializeComponent();
anylineScanView = AnylineScanView;
}
private void CameraView_CameraOpened(object sender, Size args)
{
Debug.WriteLine($"(APP) Camera Opened: {args.Width}x{args.Height}");
try
{
anylineScanView?.StartScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraClosed(object sender, bool success)
{
Debug.WriteLine($"(APP) Camera Closed: {success}");
try
{
anylineScanView?.StopScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraError(object sender, Exception exception)
{
Debug.WriteLine($"(APP) Camera Error: {exception.Message}");
}
// important because the UWP camera stream automatically shuts down when a window is minimized
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (args.Visible == false)
{
if (anylineScanView != null)
{
await anylineScanView.StopCameraAsync();
}
}
if (args.Visible == true)
{
anylineScanView?.StartCamera();
}
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
await anylineScanView.StopCameraAsync();
anylineScanView.Dispose();
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (anylineScanView == null) return;
// register events
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
anylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
anylineScanView.CameraView.CameraError += CameraView_CameraError;
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
Window.Current.VisibilityChanged += Current_VisibilityChanged;
}
string jsonConfig = (e.Parameter as ExamplePlugin).JSONConfigFile;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// the correct plugin is loaded according to the .json config file informed
scanViewPlugin = anylineScanView.ScanViewPlugin;
scanViewPlugin.AddScanResultListener(this);
anylineScanView?.StartCamera();
}
public void OnResult(ScanResult<ID> result)
{
if (result.Result is Identification id) {
// get layout definition here:
var layoutDefinition = id.LayoutDefinition;
// iterate through values of the id, because it is enumerable
foreach(var parameter in id) {
Debug.WriteLine($"Parameter name: {parameter.Key}, value: {parameter.Value}, Confidence: {id.FieldConfidences[parameter.Key]}");
}
}
}
}
}
|
Vehicle Registration Certificate (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | {
"camera" : {
"captureResolution" : "1080p"
},
"flash" : {
"mode": "manual",
"alignment": "bottom_right",
"imageOn": "flash_on",
"imageOff": "flash_off"
},
"viewPlugin" : {
"plugin":{
"id":"ID",
"idPlugin": {
"vehicleRegistrationCertificateConfig": {
"layoutVehicleCertificate": {
"documentNumber": {"scanOption": 1, "minConfidence": 40},
"licensePlate": {"scanOption": 0, "minConfidence": 40},
"lastName": {"scanOption": 0, "minConfidence": 60},
"firstName": {"scanOption": 1, "minConfidence": 40},
"address": {"scanOption": 0, "minConfidence": 50},
"firstIssued": {"scanOption": 0, "minConfidence": 60},
"manufacturerCode": {"scanOption": 0, "minConfidence": 50},
"vehicleTypeCode": {"scanOption": 0, "minConfidence": 50},
"vehicleIdentificationNumber": {"scanOption": 0, "minConfidence": 60},
"brand": {"scanOption": 1, "minConfidence": 40},
"vehicleType": {"scanOption": 1, "minConfidence": 40},
"displacement": {"scanOption": 1, "minConfidence": 40},
"tire": {"scanOption": 1, "minConfidence": 50}
}
}
}
},
"cutoutConfig" : {
"style": "animated_rect",
"maxWidthPercent": "90%",
"maxHeightPercent": "90%",
"alignment": "center",
"strokeWidth": 3,
"cornerRadius": 8,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"ratioFromSize": {
"width": 90,
"height": 46
},
"cropPadding": {
"x": -50,
"y": -50
},
"cropOffset": {
"x": 0,
"y": 0
},
"feedbackStrokeColor": "0099FF"
},
"scanFeedback" : {
"style": "CONTOUR_RECT",
"visualFeedbackRedrawTimeout": 100,
"strokeColor": "0099FF",
"fillColor" : "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"strokeWidth": 2
},
"cancelOnResult" : true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | public class ScanVehicleRegistrationCertificate extends AppCompatActivity {
ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vehicle_registration);
init();
}
void init(){
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
scanView.init("vehicle_registration_certificate_view_config.json");
IdScanViewPlugin idScanViewPlugin = (IdScanViewPlugin) scanView.getScanViewPlugin();
idScanViewPlugin.addScanResultListener((ScanResultListener<ScanResult<ID>>) idScanResult -> {
Identification identification = (Identification) idScanResult.getResult();
HashMap<String, String> data = (HashMap<String, String>) identification.getResultData();
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onStop() {
super.onStop();
scanView.stop();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | //
// ALUniversalIDViewController.m
// AnylineExamples
//
// Created by Aldrich Co on 08.12.21.
//
#import "ALUniversalIDViewController.h"
// This is the license key for the examples project used to set up Anyline below
NSString * const kUniversalIDLicenseKey = @"ADD YOUR LICENSE KEY";
@interface ALUniversalIDScanViewControllerFrontAndBack ()<ALIDPluginDelegate>
@property (nonatomic, strong) ALIDScanViewPlugin *scanViewPlugin;
@property (nonatomic, strong) ALIDScanPlugin *scanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALUniversalIDViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
// Initialise the Anyline License
NSError *licenseError = nil;
[AnylineSDK setupWithLicenseKey:kUniversalIDLicenseKey error:&licenseError];
if (licenseError) {
// Handle the error. You would be unable to use the scan view and scan plugin
// in the event of an error, so it may be a good idea to make an early return.
}
NSError *error = nil;
NSString *jsonFilePath = [[NSBundle mainBundle] pathForResource:@"universal_id_config"
ofType:@"json"];
NSData *jsonFile = [NSData dataWithContentsOfFile:jsonFilePath];
NSDictionary *configDict = [NSJSONSerialization JSONObjectWithData:jsonFile
options:NSJSONReadingMutableContainers
error:&error];
// Initialise the scan view plugin using the JSON configuration file and setting oneself
// as its ALIDPluginDelegate
self.scanViewPlugin = (ALIDScanViewPlugin *)[ALAbstractScanViewPlugin scanViewPluginForConfigDict:configDict delegate:self error:&error];
NSAssert(self.scanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanPlugin = self.scanViewPlugin.idScanPlugin;
// Implement ALScanViewPluginDelegate for its `anylineScanViewPlugin:updatedCutout:` method
// [self.scanViewPlugin addScanViewPluginDelegate:self];
// Implement ALInfoDelegate if interested in meta-variables reported while scanning
// [self.scanPlugin addInfoDelegate:self];
// Set the scanView's frame to fill the whole screen
CGRect frame = [self scanViewFrame];
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scanViewPlugin];
// You can still configure the scan view config until the plugin is started;
// here we set the flash button position within the scan view
self.scanView.flashButtonConfig.flashAlignment = ALFlashAlignmentTopLeft;
// After setup is complete we add the scanView to the view of this view controller
[self.view addSubview:self.scanView];
[self.scanView startCamera];
}
/*
Start the scanning process once the view hierarchy has appeared onscreen.
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.scanViewPlugin stopAndReturnError:nil];
[super viewWillDisappear:animated];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found, scanning will stop automatically (you can change this behaviour
with cancelOnResult:).
*/
- (void)startAnyline {
NSError *error = nil;
[self.scanViewPlugin startAndReturnError:&error];
// Handle if error is not null here
}
// MARK: - ALIDPluginDelegate
/*
This is the main delegate method Anyline uses to report its results.
*/
- (void)anylineIDScanPlugin:(ALIDScanPlugin *)anylineIDScanPlugin
didFindResult:(ALIDResult *)scanResult {
ALUniversalIDIdentification *identification = (ALUniversalIDIdentification *)scanResult.result;
NSArray<NSString *> *fieldNames = identification.fieldNames;
ALLayoutDefinition *layoutDefinition = identification.layoutDefinition;
ALUniversalIDFieldConfidences *fieldConfidences = identification.fieldConfidences;
UIImage *faceImage = identification.faceImage;
// Handle your result here
// ...
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Barcode;
using Anyline.SDK.Plugins.ID;
using Anyline.SDK.Plugins.LicensePlate;
using Anyline.SDK.Plugins.Meter;
using Anyline.SDK.Plugins.OCR;
using Anyline.SDK.Plugins.ViewPlugins;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Windows.Foundation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
using Anyline.SDK.Views;
using Anyline.SDK.Plugins.ID;
namespace Anyline_Windows_UWP_Examples
{
public sealed partial class ScanViewPage : Page,
IScanResultListener<ScanResult<ID>>
{
private ScanView anylineScanView;
private IViewPluginBase scanViewPlugin;
public ScanViewPage()
{
// We don't want to keep multiple instances of the scan views that we're navigating to.
NavigationCacheMode = NavigationCacheMode.Required;
((Frame)Window.Current.Content).CacheSize = 0;
this.InitializeComponent();
anylineScanView = AnylineScanView;
}
private void CameraView_CameraOpened(object sender, Size args)
{
Debug.WriteLine($"(APP) Camera Opened: {args.Width}x{args.Height}");
try
{
anylineScanView?.StartScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraClosed(object sender, bool success)
{
Debug.WriteLine($"(APP) Camera Closed: {success}");
try
{
anylineScanView?.StopScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraError(object sender, Exception exception)
{
Debug.WriteLine($"(APP) Camera Error: {exception.Message}");
}
// important because the UWP camera stream automatically shuts down when a window is minimized
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (args.Visible == false)
{
if (anylineScanView != null)
{
await anylineScanView.StopCameraAsync();
}
}
if (args.Visible == true)
{
anylineScanView?.StartCamera();
}
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
await anylineScanView.StopCameraAsync();
anylineScanView.Dispose();
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (anylineScanView == null) return;
// register events
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
anylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
anylineScanView.CameraView.CameraError += CameraView_CameraError;
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
Window.Current.VisibilityChanged += Current_VisibilityChanged;
}
string jsonConfig = (e.Parameter as ExamplePlugin).JSONConfigFile;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// the correct plugin is loaded according to the .json config file informed
scanViewPlugin = anylineScanView.ScanViewPlugin;
scanViewPlugin.AddScanResultListener(this);
anylineScanView?.StartCamera();
}
public void OnResult(ScanResult<ID> result)
{
if (result.Result is Identification id) {
// get layout definition here:
var layoutDefinition = id.LayoutDefinition;
// iterate through values of the id, because it is enumerable
foreach(var parameter in id) {
Debug.WriteLine($"Parameter name: {parameter.Key}, value: {parameter.Value}, Confidence: {id.FieldConfidences[parameter.Key]}");
}
}
}
}
}
|
License Plate Plugin (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | {
"camera": {
"captureResolution": "1080p",
"zoomGesture": true
},
"flash": {
"mode": "manual",
"alignment": "top_left"
},
"viewPlugin": {
"plugin": {
"id": "LicensePlate_ID",
"licensePlatePlugin": {
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"maxHeightPercent": "80%",
"alignment": "top_half",
"width": 720,
"ratioFromSize": {
"width": 2,
"height": 1
},
"strokeWidth": 2,
"cornerRadius": 10,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"animationDuration": 0,
"style": "RECT",
"strokeWidth": 2,
"strokeColor": "0099FF",
"blinkOnResult": true,
"beepOnResult": true,
"vibrateOnResult": true
},
"cancelOnResult": true,
"delayStartScanTime": 2000
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.licenseplate.LicensePlateScanResult;
import io.anyline.plugin.licenseplate.LicensePlateScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanLicensePlateActivity extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
//init the scan view
scanView.init("license_plate_view_config.json");
LicensePlateScanViewPlugin scanViewPlugin = (LicensePlateScanViewPlugin) scanView.getScanViewPlugin();
scanView.setScanViewPlugin(scanViewPlugin);
// add the result listener
scanViewPlugin.addScanResultListener(new ScanResultListener<LicensePlateScanResult>() {
@Override
public void onResult(LicensePlateScanResult result) {
Toast.makeText(getApplicationContext(), result.getCountry(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | #import "ALLicensePlateViewController.h"
#import <Anyline/Anyline.h>
#import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALAppDemoLicenses.h"
#import "ALResultEntry.h"
#import "ALResultViewController.h"
#import "Anyline/ALMeterScanPlugin.h"
#import "Anyline/ALMeterScanViewPlugin.h"
// This is the license key for the examples project used to set up Aynline below
NSString * const kLicensePlateLicenseKey = kDemoAppLicenseKey;
// The controller has to conform to <AnylineOCRModuleDelegate> to be able to receive results
@interface ALLicensePlateViewController ()<ALLicensePlateScanPluginDelegate, ALInfoDelegate>
// The Anyline module used for OCR
@property (nonatomic, strong) ALLicensePlateScanViewPlugin *licensePlateScanViewPlugin;
@property (nonatomic, strong) ALLicensePlateScanPlugin *licensePlateScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALLicensePlateViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"License Plate";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kDemoAppLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
NSError *error = nil;
self.licensePlateScanPlugin = [[ALLicensePlateScanPlugin alloc] initWithPluginID:@"LICENSE_PLATE" delegate:self error:&error];
NSAssert(self.licensePlateScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.licensePlateScanPlugin addInfoDelegate:self];
self.licensePlateScanViewPlugin = [[ALLicensePlateScanViewPlugin alloc] initWithScanPlugin:self.licensePlateScanPlugin];
NSAssert(self.licensePlateScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.licensePlateScanViewPlugin];
self.controllerType = ALScanHistoryLicensePlates;
// After setup is complete we add the module to the view of this view controller
[self.view addSubview:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self.view sendSubviewToBack:self.scanView];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
NSError *error;
BOOL success = [self.licensePlateScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
NSAssert(success, @"Start Scanning Error: %@", error.debugDescription);
}
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.licensePlateScanViewPlugin stopAndReturnError:nil];
}
#pragma mark -- AnylineOCRModuleDelegate
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineLicensePlateScanPlugin:(ALLicensePlateScanPlugin *)anylineLicensePlateScanPlugin
didFindResult:(ALLicensePlateResult *)result {
//Handle the returned scan Result here.
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.LicensePlate;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<LicensePlateScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as LicensePlateScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(LicensePlateScanResult result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
Tire Plugin : TIN Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | {
"camera": {
"captureResolution": "720"
},
"flash": {
"mode": "manual",
"alignment": "bottom_left"
},
"viewPlugin": {
"plugin": {
"id": "TIN_ID",
"tirePlugin": {
"tinConfig": {
"scanMode": "UNIVERSAL",
"upsideDownMode": "auto"
}
}
},
"cutoutConfig": {
"style": "rect",
"width": 720,
"alignment": "center",
"maxWidthPercent": "80%",
"ratioFromSize": {
"width": 720,
"height": 144
},
"strokeWidth": 2,
"strokeColor": "FFFFFF",
"cornerRadius": 4,
"outerColor": "000000",
"outerAlpha": 0.5,
"feedbackStrokeColor": "0099FF",
"offset": {
"x": 0,
"y": -15
}
},
"scanFeedback": {
"animation": "traverse_multi",
"animationDuration": 250,
"style": "contour_rect",
"strokeWidth": 2,
"strokeColor": "0099FF",
"beepOnResult": false,
"vibrateOnResult": true,
"blinkAnimationOnResult": true,
"cancelOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.anyline.examples.demo;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.tire.TINConfig;
import io.anyline.plugin.tire.TireScanResult;
import io.anyline.plugin.tire.TireScanViewPlugin;
import io.anyline.view.BaseScanViewConfig;
import io.anyline.view.ScanView;
import io.anyline.view.ScanViewPluginConfig;
import io.anyline.AnylineSDK;
import at.nineyards.anyline.core.LicenseException;
public class ScanTINActivity extends AppCompatActivity {
private static final String TAG = ScanTINActivity.class.getSimpleName();
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_scan_tire);
String lic = getString(R.string.anyline_license_key);
scanView = (ScanView) findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(lic), this);
} catch (LicenseException e) {
// handle exception
}
//init the scanView with the JSON config file
scanView.init("tire_config.json");
//add the scan result listener
scanView.getScanViewPlugin().addScanResultListener(new ScanResultListener<TireScanResult>() {
@Override
public void onResult(TireScanResult result) {
if (!result.toString().isEmpty()) {
Toast.makeText(getApplicationContext(), result.getResult(), Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
//start the scanning
//internally scanView is calling the scanPlugin which is starting the scanning part
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #import "ALTINScanViewController.h"
@interface ALTINScanViewController() <ALTireScanPluginDelegate, ALScanViewPluginDelegate>
// The Anyline plugin used for tire scanning
@property (nonatomic, strong) ALTireScanPlugin *tireScanPlugin;
@property (nonatomic, strong) ALTireScanViewPlugin *tireScanViewPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALTINScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Tire Identification Number";
// We will be setting up the tire plugin with the TIN Config: Universal TIN scan mode. Other
// scan modes for the TIN Config include: ALTINDotStrict and ALTINDotStrict.
//
// Apart from ALTINConfig, other tire plugin configs are available: ALTireSizeConfig and
// ALCommercialTireIdConfig
ALTINConfig *config = [[ALTINConfig alloc] init];
[config setScanMode:ALTINUniversal];
// Initialize the tire plugin here. If there is an error, scanning would not be possible.
// This case will need to be handled in the appropriate manner.
NSError *error = nil;
self.tireScanPlugin = [[ALTireScanPlugin alloc] initWithPluginID:@"TIRE"
delegate:self
tireConfig:config
error:&error];
NSAssert(self.tireScanPlugin, @"Setup Error: %@", error.debugDescription);
// Configure the scan view config, setting it up using the tireScanPlugin initialized
// previously.
ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultTINConfig];
viewPluginConfig.delayStartScanTime = 2000;
self.tireScanViewPlugin = [[ALTireScanViewPlugin alloc] initWithScanPlugin:self.tireScanPlugin
scanViewPluginConfig:viewPluginConfig];
// Set the delegate for the scan view plugin to be notified when a result has been found.
[self.tireScanViewPlugin addScanViewPluginDelegate:self];
// Finally, initialize the scan view, which is a UIView subclass, with the scan view plugin.
// We set the frame initially to CGRectZero, but later use autolayout constraints to allow
// the scan view to fill the entire screen.
self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero scanViewPlugin:self.tireScanViewPlugin];
// After setup is complete we add the scanView to the view of this view controller.
[self.view addSubview:self.scanView];
[self setupConstraints];
// Start the camera.
[self.scanView startCamera];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Start the tire scan plugin to begin scanning, the moment the scan view appears.
[self startPlugin:self.tireScanViewPlugin];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.tireScanViewPlugin stopAndReturnError:nil];
}
- (void)setupConstraints {
self.scanView.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *constraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
[self.scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor],
[self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]];
[self.view addConstraints:constraints];
[NSLayoutConstraint activateConstraints:constraints];
}
// MARK: - ALTireScanPluginDelegate
- (void)anylineTireScanPlugin:(ALTireScanPlugin * _Nonnull)anylineTireScanPlugin
didFindResult:(ALTireResult * _Nonnull)tireScanResult {
// The plugin is stopped when the result is returned. You may at some later
// point decide to start the plugin again, depending on your needs. Here,
// the tire scan result is used.
NSLog(@"Tire Scan Result: %@", tireScanResult.result);
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Tire;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<TireScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as TireScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<TireScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
Tire Plugin : Tire Size Specifications Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | {
"camera": {
"captureResolution": "1080"
},
"flash": {
"mode": "manual",
"alignment": "bottom_left"
},
"viewPlugin": {
"plugin": {
"id": "TIRE_SIZE_ID",
"tirePlugin": {
"tireSizeConfig": {
}
}
},
"cutoutConfig": {
"style": "rect",
"width": 720,
"alignment": "center",
"maxWidthPercent": "80%",
"ratioFromSize": {
"width": 720,
"height": 144
},
"strokeWidth": 2,
"strokeColor": "FFFFFF",
"cornerRadius": 4,
"outerColor": "000000",
"outerAlpha": 0.5,
"feedbackStrokeColor": "0099FF",
"offset": {
"x": 0,
"y": -15
}
},
"scanFeedback": {
"animation": "traverse_multi",
"animationDuration": 250,
"style": "rect",
"strokeWidth": 2,
"strokeColor": "0099FF",
"beepOnResult": false,
"vibrateOnResult": true,
"blinkAnimationOnResult": true,
"cancelOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.anyline.examples.demo;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.tire.TINConfig;
import io.anyline.plugin.tire.TireScanResult;
import io.anyline.plugin.tire.TireScanViewPlugin;
import io.anyline.view.BaseScanViewConfig;
import io.anyline.view.ScanView;
import io.anyline.view.ScanViewPluginConfig;
import io.anyline.AnylineSDK;
import at.nineyards.anyline.core.LicenseException;
public class ScanTINActivity extends AppCompatActivity {
private static final String TAG = ScanTINActivity.class.getSimpleName();
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_scan_tire);
String lic = getString(R.string.anyline_license_key);
scanView = (ScanView) findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(lic), this);
} catch (LicenseException e) {
// handle exception
}
//init the scanView with the JSON config file
scanView.init("tire_config.json");
//add the scan result listener
scanView.getScanViewPlugin().addScanResultListener(new ScanResultListener<TireScanResult>() {
@Override
public void onResult(TireScanResult result) {
if (!result.toString().isEmpty()) {
Toast.makeText(getApplicationContext(), result.getResult(), Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
//start the scanning
//internally scanView is calling the scanPlugin which is starting the scanning part
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #import "ALTINScanViewController.h"
@interface ALTINScanViewController() <ALTireScanPluginDelegate, ALScanViewPluginDelegate>
// The Anyline plugin used for tire scanning
@property (nonatomic, strong) ALTireScanPlugin *tireScanPlugin;
@property (nonatomic, strong) ALTireScanViewPlugin *tireScanViewPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALTINScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Tire Size Specification";
ALTireSizeConfig *config = [[ALTireSizeConfig alloc] init];
// Initialize the tire plugin here. If there is an error, scanning would not be possible.
// This case will need to be handled in the appropriate manner.
NSError *error = nil;
self.tireScanPlugin = [[ALTireScanPlugin alloc] initWithPluginID:@"TIRE"
delegate:self
tireConfig:config
error:&error];
NSAssert(self.tireScanPlugin, @"Setup Error: %@", error.debugDescription);
// Configure the scan view config, setting it up using the tireScanPlugin initialized
// previously.
ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultTINConfig];
viewPluginConfig.delayStartScanTime = 2000;
self.tireScanViewPlugin = [[ALTireScanViewPlugin alloc] initWithScanPlugin:self.tireScanPlugin
scanViewPluginConfig:viewPluginConfig];
// Set the delegate for the scan view plugin to be notified when a result has been found.
[self.tireScanViewPlugin addScanViewPluginDelegate:self];
// Finally, initialize the scan view, which is a UIView subclass, with the scan view plugin.
// We set the frame initially to CGRectZero, but later use autolayout constraints to allow
// the scan view to fill the entire screen.
self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero scanViewPlugin:self.tireScanViewPlugin];
// After setup is complete we add the scanView to the view of this view controller.
[self.view addSubview:self.scanView];
[self setupConstraints];
// Start the camera.
[self.scanView startCamera];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Start the tire scan plugin to begin scanning, the moment the scan view appears.
[self startPlugin:self.tireScanViewPlugin];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.tireScanViewPlugin stopAndReturnError:nil];
}
- (void)setupConstraints {
self.scanView.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *constraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
[self.scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor],
[self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]];
[self.view addConstraints:constraints];
[NSLayoutConstraint activateConstraints:constraints];
}
// MARK: - ALTireScanPluginDelegate
- (void)anylineTireScanPlugin:(ALTireScanPlugin * _Nonnull)anylineTireScanPlugin
didFindResult:(ALTireResult * _Nonnull)tireScanResult {
// The plugin is stopped when the result is returned. You may at some later
// point decide to start the plugin again, depending on your needs. Here,
// the tire scan result is used.
NSLog(@"Tire Scan Result: %@", tireScanResult.result);
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Tire;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<TireScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as TireScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<TireScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
Tire Plugin : Commercial Tire ID Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | {
"camera": {
"captureResolution": "1080"
},
"flash": {
"mode": "manual",
"alignment": "bottom_left"
},
"viewPlugin": {
"plugin": {
"id": "COMMERCIAL_TIRE_ID",
"tirePlugin": {
"commercialTireIdConfig": {
}
}
},
"cutoutConfig": {
"style": "rect",
"width": 720,
"alignment": "center",
"maxWidthPercent": "80%",
"ratioFromSize": {
"width": 720,
"height": 144
},
"strokeWidth": 2,
"strokeColor": "FFFFFF",
"cornerRadius": 4,
"outerColor": "000000",
"outerAlpha": 0.5,
"feedbackStrokeColor": "0099FF",
"offset": {
"x": 0,
"y": -15
}
},
"scanFeedback": {
"animation": "traverse_multi",
"animationDuration": 250,
"style": "contour_rect",
"strokeWidth": 2,
"strokeColor": "0099FF",
"beepOnResult": false,
"vibrateOnResult": true,
"blinkAnimationOnResult": true,
"cancelOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | package com.anyline.examples.demo;
import android.os.Bundle;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.tire.TINConfig;
import io.anyline.plugin.tire.TireScanResult;
import io.anyline.plugin.tire.TireScanViewPlugin;
import io.anyline.view.BaseScanViewConfig;
import io.anyline.view.ScanView;
import io.anyline.view.ScanViewPluginConfig;
import io.anyline.AnylineSDK;
import at.nineyards.anyline.core.LicenseException;
public class ScanTINActivity extends AppCompatActivity {
private static final String TAG = ScanTINActivity.class.getSimpleName();
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_scan_tire);
String lic = getString(R.string.anyline_license_key);
scanView = (ScanView) findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(lic), this);
} catch (LicenseException e) {
// handle exception
}
//init the scanView with the JSON config file
scanView.init("tire_config.json");
//add the scan result listener
scanView.getScanViewPlugin().addScanResultListener(new ScanResultListener<TireScanResult>() {
@Override
public void onResult(TireScanResult result) {
if (!result.toString().isEmpty()) {
Toast.makeText(getApplicationContext(), result.getResult(), Toast.LENGTH_LONG).show();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
//start the scanning
//internally scanView is calling the scanPlugin which is starting the scanning part
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #import "ALTINScanViewController.h"
@interface ALTINScanViewController() <ALTireScanPluginDelegate, ALScanViewPluginDelegate>
// The Anyline plugin used for tire scanning
@property (nonatomic, strong) ALTireScanPlugin *tireScanPlugin;
@property (nonatomic, strong) ALTireScanViewPlugin *tireScanViewPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALTINScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Commercial Tire ID";
ALCommercialTireIdConfig *config = [[ALCommercialTireIdConfig alloc] init];
// Initialize the tire plugin here. If there is an error, scanning would not be possible.
// This case will need to be handled in the appropriate manner.
NSError *error = nil;
self.tireScanPlugin = [[ALTireScanPlugin alloc] initWithPluginID:@"TIRE"
delegate:self
tireConfig:config
error:&error];
NSAssert(self.tireScanPlugin, @"Setup Error: %@", error.debugDescription);
// Configure the scan view config, setting it up using the tireScanPlugin initialized
// previously.
ALScanViewPluginConfig *viewPluginConfig = [ALScanViewPluginConfig defaultTINConfig];
viewPluginConfig.delayStartScanTime = 2000;
self.tireScanViewPlugin = [[ALTireScanViewPlugin alloc] initWithScanPlugin:self.tireScanPlugin
scanViewPluginConfig:viewPluginConfig];
// Set the delegate for the scan view plugin to be notified when a result has been found.
[self.tireScanViewPlugin addScanViewPluginDelegate:self];
// Finally, initialize the scan view, which is a UIView subclass, with the scan view plugin.
// We set the frame initially to CGRectZero, but later use autolayout constraints to allow
// the scan view to fill the entire screen.
self.scanView = [[ALScanView alloc] initWithFrame:CGRectZero scanViewPlugin:self.tireScanViewPlugin];
// After setup is complete we add the scanView to the view of this view controller.
[self.view addSubview:self.scanView];
[self setupConstraints];
// Start the camera.
[self.scanView startCamera];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Start the tire scan plugin to begin scanning, the moment the scan view appears.
[self startPlugin:self.tireScanViewPlugin];
}
/*
Cancel scanning to allow the module to clean up.
*/
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.tireScanViewPlugin stopAndReturnError:nil];
}
- (void)setupConstraints {
self.scanView.translatesAutoresizingMaskIntoConstraints = NO;
NSArray *constraints = @[[self.scanView.topAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.topAnchor],
[self.scanView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor],
[self.scanView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor],
[self.scanView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor]];
[self.view addConstraints:constraints];
[NSLayoutConstraint activateConstraints:constraints];
}
// MARK: - ALTireScanPluginDelegate
- (void)anylineTireScanPlugin:(ALTireScanPlugin * _Nonnull)anylineTireScanPlugin
didFindResult:(ALTireResult * _Nonnull)tireScanResult {
// The plugin is stopped when the result is returned. You may at some later
// point decide to start the plugin again, depending on your needs. Here,
// the tire scan result is used.
NSLog(@"Tire Scan Result: %@", tireScanResult.result);
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Tire;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<TireScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as TireScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<TireScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
AnylineOCR Plugin : Universal Serial Number Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | {
"camera": {
"captureResolution": "720"
},
"flash": {
"mode": "manual",
"alignment": "bottom_right"
},
"viewPlugin": {
"plugin": {
"id": "USNR_ID",
"ocrPlugin": {
"ocrConfig" : {
"scanMode" : "AUTO"
}
}
},
"cutoutConfig": {
"style": "rect",
"width": 720,
"alignment": "top_half",
"maxWidthPercent": "80%",
"ratioFromSize": {
"width": 720,
"height": 144
},
"strokeWidth": 2,
"strokeColor": "FFFFFF",
"cornerRadius": 4,
"outerColor": "000000",
"outerAlpha": 0.5,
"feedbackStrokeColor": "0099FF",
"offset": {
"x": 0,
"y": -15
}
},
"scanFeedback": {
"style": "CONTOUR_RECT",
"strokeColor": "0099FF",
"fillColor": "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanUSNrActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("usnr_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Barcode;
using Anyline.SDK.Plugins.ID;
using Anyline.SDK.Plugins.LicensePlate;
using Anyline.SDK.Plugins.Meter;
using Anyline.SDK.Plugins.OCR;
using Anyline.SDK.Plugins.ViewPlugins;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanViewPage : Page,
IScanResultListener<BarcodeScanResult>,
IScanResultListener<ScanResult<ID>>,
IScanResultListener<LicensePlateScanResult>,
IScanResultListener<MeterScanResult>,
IScanResultListener<OCRScanResult>,
IPhotoCaptureListener
{
private ScanView anylineScanView;
private IViewPluginBase scanViewPlugin;
public ScanViewPage()
{
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(MY_LICENSE_KEY);
// We don't want to keep multiple instances of the scan views that we're navigating to.
NavigationCacheMode = NavigationCacheMode.Required;
((Frame)Window.Current.Content).CacheSize = 0;
ApplicationView.GetForCurrentView().Title = "Anyline Examples";
this.InitializeComponent();
//AnylineDebug.SetVerbosity(Verbosity.Diagnostic);
anylineScanView = AnylineScanView;
}
private void CameraView_CameraOpened(object sender, Size args)
{
Debug.WriteLine($"(APP) Camera Opened: {args.Width}x{args.Height}");
try
{
anylineScanView?.StartScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraClosed(object sender, bool success)
{
Debug.WriteLine($"(APP) Camera Closed: {success}");
try
{
anylineScanView?.StopScanning();
}
catch (Exception e)
{
Debug.WriteLine($"(APP) {e.Message}");
}
}
private void CameraView_CameraError(object sender, Exception exception)
{
Debug.WriteLine($"(APP) Camera Error: {exception.Message}");
}
// important because the UWP camera stream automatically shuts down when a window is minimized
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (args.Visible == false)
{
if (anylineScanView != null)
{
await anylineScanView.StopCameraAsync();
}
}
if (args.Visible == true)
{
anylineScanView?.StartCamera();
}
}
protected override async void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
await anylineScanView.StopCameraAsync();
anylineScanView.Dispose();
}
}
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (anylineScanView == null) return;
// register events
if (anylineScanView != null)
{
anylineScanView.CameraView.CameraOpened -= CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed -= CameraView_CameraClosed;
anylineScanView.CameraView.CameraError -= CameraView_CameraError;
anylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
anylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
anylineScanView.CameraView.CameraError += CameraView_CameraError;
Window.Current.VisibilityChanged -= Current_VisibilityChanged;
Window.Current.VisibilityChanged += Current_VisibilityChanged;
}
ApplicationView.GetForCurrentView().Title = (e.Parameter as ExamplePlugin).Name;
string jsonConfig = (e.Parameter as ExamplePlugin).JSONConfigFile;
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// the correct plugin is loaded according to the .json config file informed
scanViewPlugin = anylineScanView.ScanViewPlugin;
scanViewPlugin.AddScanResultListener(this);
if (scanViewPlugin is PhotoCaptureViewPlugin photoCapturePlugin)
{
photoCapturePlugin.PhotoCaptureListener = this;
photoCapturePlugin.PhotoCaptureTarget = PhotoCaptureTarget.File;
}
anylineScanView?.StartCamera();
}
public void OnResult(LicensePlateScanResult result)
{
OpenResultsPage(result.CreatePropertyDictionary());
}
public void OnResult(BarcodeScanResult result)
{
OpenResultsPage(result.CreatePropertyDictionary());
}
public void OnResult(MeterScanResult result)
{
OpenResultsPage(result.CreatePropertyDictionary());
}
public void OnResult(OCRScanResult result)
{
OpenResultsPage(result.CreatePropertyDictionary());
}
public void OnResult(ScanResult<ID> result)
{
OpenResultsPage(result.CreatePropertyDictionary());
}
private void OpenResultsPage(Dictionary<string, object> dictionary)
{
/// in our example app, we dynamically extract result values from the object via reflection.
/// Usually, you can just use the result on the object type that matches your ScanPlugin type (e.g. ALMeterResult for ALMeterScanPlugin etc.) and access the properties directly
(Window.Current.Content as Frame).Navigate(typeof(ResultsPage), dictionary);
}
public void OnPhotoCaptured(AnylineImage anylineImage)
{
var result = new Dictionary<string, object> { };
result.Add("Image result", anylineImage);
(Window.Current.Content as Frame).Navigate(typeof(ResultsPage), result);
}
public async void OnPhotoToFile(StorageFile file)
{
BitmapImage bitmapImage = new BitmapImage();
FileRandomAccessStream stream = (FileRandomAccessStream)await file.OpenAsync(FileAccessMode.Read);
bitmapImage.SetSource(stream);
var result = new Dictionary<string, object> { };
result.Add("Image result", bitmapImage);
(Window.Current.Content as Frame).Navigate(typeof(ResultsPage), result);
}
}
}
|
AnylineOCR Plugin : VIN Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | {
"camera": {
"captureResolution": "1080p",
"zoomGesture": true
},
"flash": {
"mode": "manual",
"alignment": "bottom_right",
"imageOn": "flash_on",
"imageOff": "flash_off"
},
"viewPlugin": {
"plugin": {
"id": "VIN_ID",
"ocrPlugin": {
"vinConfig":{
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "70%",
"alignment": "top_half",
"ratioFromSize": {
"width": 62,
"height": 9
},
"strokeWidth": 2,
"strokeColor": "FFFFFF",
"cornerRadius": 4,
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"animation": "traverse_multi",
"animationDuration": 250,
"style": "contour_rect",
"strokeWidth": 2,
"strokeColor": "0099FF",
"fillColor": "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
},
"cancelOnResult": true,
"reportingEnabled": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanVINActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("vin_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | // The Anyline plugin used for OCR
@property (nonatomic, strong) ALOCRScanViewPlugin *vinScanViewPlugin;
@property (nonatomic, strong) ALOCRScanPlugin *vinScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALVINScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"VIN";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kVINLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
ALVINConfig *config = [[ALVINConfig alloc] init];
NSError *error = nil;
self.vinScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR"
delegate:self
ocrConfig:config
error:&error];
NSAssert(self.vinScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.vinScanPlugin addInfoDelegate:self];
//Set a custom Anyline JSON config
NSString *confPath = [[NSBundle mainBundle] pathForResource:@"vin_capture_config" ofType:@"json"];
ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath];
self.vinScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.vinScanPlugin
scanViewPluginConfig:scanViewPluginConfig];
NSAssert(self.vinScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.vinScanViewPlugin];
//Enable Zoom Gesture
[self.scanView enableZoomPinchGesture:YES];
// After setup is complete we add the scanView to the view of this view controller
[self.view addSubview:self.scanView];
[self.view sendSubviewToBack:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self startListeningForMotion];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
NSError *error;
BOOL success = [self.vinScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
NSAssert(success, @"Start Scanning Error: %@", error.debugDescription);
}
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.vinScanViewPlugin stopAndReturnError:nil];
}
#pragma mark -- anylineOCRScanPlugin
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin
didFindResult:(ALOCRResult *)result {
//Handle the result here:
NSLog(@"Result: %@", result.result);
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{
if ([info.variableName isEqualToString:@"$brightness"]) {
[self updateBrightness:[info.value floatValue] forModule:self.scrabbleScanViewPlugin];
}
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin runSkipped:(ALRunSkippedReason *)runSkippedReason {
//Handle run skipped reasons here:
switch (runSkippedReason.reason) {
case ALRunFailureResultNotValid:
break;
case ALRunFailureConfidenceNotReached:
break;
case ALRunFailureNoLinesFound:
break;
case ALRunFailureNoTextFound:
break;
case ALRunFailureUnkown:
break;
default:
break;
}
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Ocr;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<OcrScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as OcrScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<OcrScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
AnylineOCR Plugin : Shipping Container Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | {
"camera": {
"captureResolution": "1080",
"zoomGesture": true
},
"flash": {
"mode": "manual",
"alignment": "bottom_right",
"imageOn": "flash_on",
"imageOff": "flash_off"
},
"viewPlugin": {
"plugin" : {
"id" : "CONTAINER",
"ocrPlugin" : {
"containerConfig":{
"scanMode": "horizontal"
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"alignment": "top_half",
"width": 720,
"ratioFromSize": {
"width": 720,
"height": 144
},
"strokeWidth": 2,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF",
"offset": {
"x": 0,
"y": -15
}
},
"scanFeedback": {
"style": "CONTOUR_RECT",
"strokeWidth": 2,
"strokeColor": "0099FF",
"fillColor" : "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanShippingContainerActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("shipping_container_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Ocr;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<OcrScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/mro_config_shipping_container.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as OcrScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<OcrScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
AnylineOCR Plugin : Cattle Tag Scan Mode (Documentation)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | {
"camera": {
"captureResolution": "720",
"zoomGesture": true
},
"flash": {
"mode": "manual",
"alignment": "bottom_right"
},
"viewPlugin": {
"plugin": {
"id": "CATTLE_TAG",
"ocrPlugin": {
"cattleTagConfig":{
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"maxHeightPercent": "80%",
"alignment": "center",
"width": 600,
"ratioFromSize": {
"width": 1,
"height": 1
},
"strokeWidth": 2,
"cornerRadius": 10,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF",
"cropPadding": {
"x": 60,
"y": 60
},
"cropOffset": {
"x": 0,
"y": 0
}
},
"cancelOnResult": false,
"scanFeedback": {
"style": "rect",
"strokeWidth": 2,
"strokeColor": "0099FF",
"fillColor": "330099FF",
"cornerRadius": 0,
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanCattleTagActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("cattle_tag_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | // The Anyline plugin used for OCR
@property (nonatomic, strong) ALOCRScanViewPlugin *cattleTagScanViewPlugin;
@property (nonatomic, strong) ALOCRScanPlugin *cattleTagScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALCattleTagScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"CattleTag";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kCattleTagLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
ALCattleTagConfig *config = [[ALCattleTagConfig alloc] init];
NSError *error = nil;
self.cattleTagScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR"
delegate:self
ocrConfig:config
error:&error];
NSAssert(self.cattleTagScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.cattleTagScanPlugin addInfoDelegate:self];
//Set a custom Anyline JSON config
NSString *confPath = [[NSBundle mainBundle] pathForResource:@"cattle_tag_capture_config" ofType:@"json"];
ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath];
self.cattleTagScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.cattleTagScanPlugin
scanViewPluginConfig:scanViewPluginConfig];
NSAssert(self.cattleTagScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.cattleTagScanViewPlugin];
//Enable Zoom Gesture
[self.scanView enableZoomPinchGesture:YES];
// After setup is complete we add the scanView to the view of this view controller
[self.view addSubview:self.scanView];
[self.view sendSubviewToBack:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self startListeningForMotion];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
NSError *error;
BOOL success = [self.cattleTagScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
NSAssert(success, @"Start Scanning Error: %@", error.debugDescription);
}
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.cattleTagScanViewPlugin stopAndReturnError:nil];
}
#pragma mark -- anylineOCRScanPlugin
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin
didFindResult:(ALOCRResult *)result {
//Handle the result here:
NSLog(@"Result: %@", result.result);
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{
if ([info.variableName isEqualToString:@"$brightness"]) {
[self updateBrightness:[info.value floatValue] forModule:self.scrabbleScanViewPlugin];
}
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin runSkipped:(ALRunSkippedReason *)runSkippedReason {
//Handle run skipped reasons here:
switch (runSkippedReason.reason) {
case ALRunFailureResultNotValid:
break;
case ALRunFailureConfidenceNotReached:
break;
case ALRunFailureNoLinesFound:
break;
case ALRunFailureNoTextFound:
break;
case ALRunFailureUnkown:
break;
default:
break;
}
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Ocr;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<OcrScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/others_config_cow_tag.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as OcrScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(ScanResult<OcrScanResult> result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
AnylineOCR Plugin
AUTO
: Scrabble1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | {
"camera": {
"captureResolution": "720"
},
"flash": {
"mode": "manual",
"alignment": "bottom_right",
"imageOn": "flash_on",
"imageOff": "flash_off"
},
"viewPlugin": {
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"maxHeightPercent": "80%",
"alignment": "center",
"width": 600,
"ratioFromSize": {
"width": 4,
"height": 1
},
"strokeWidth": 2,
"cornerRadius": 4,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"style": "contour_point",
"strokeWidth": 2,
"strokeColor": "0099FF",
"fillColor": "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanScrabbleActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("scrable_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #import "ALScrabbleScanViewController.h"
#import <Anyline/Anyline.h>
#import "ALScrabbleViewController.h"
#import "ALCustomBarButton.h"
#import "ScanHistory.h"
#import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALAppDemoLicenses.h"
// This is the license key for the examples project used to set up Aynline below
NSString * const kScrabbleLicenseKey = kDemoAppLicenseKey;
// The controller has to conform to <AnylineOCRModuleDelegate> to be able to receive results
@interface ALScrabbleScanViewController ()<ALOCRScanPluginDelegate, ALInfoDelegate>
// The Anyline plugin used for OCR
@property (nonatomic, strong) ALOCRScanViewPlugin *scrabbleScanViewPlugin;
@property (nonatomic, strong) ALOCRScanPlugin *scrabbleScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALScrabbleScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"Scrabble";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kScrabbleLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
ALOCRConfig *config = [[ALOCRConfig alloc] init];
config.scanMode = ALAuto;
config.charWhiteList = @"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÜÖ";
config.validationRegex = @"^[A-ZÄÜÖ]{7,10}$";
NSError *error = nil;
self.scrabbleScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR"
delegate:self
ocrConfig:config
error:&error];
NSAssert(self.scrabbleScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.scrabbleScanPlugin addInfoDelegate:self];
NSString *confPath = [[NSBundle mainBundle] pathForResource:@"scrabble_config" ofType:@"json"];
ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath];
self.scrabbleScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.scrabbleScanPlugin
scanViewPluginConfig:scanViewPluginConfig];
NSAssert(self.scrabbleScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.scrabbleScanViewPlugin];
// After setup is complete we add the module to the view of this view controller
[self.view addSubview:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self.view sendSubviewToBack:self.scanView];
[self startListeningForMotion];
self.controllerType = ALScanHistoryScrabble;
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
//Update Position of Warning Indicator
[self updateWarningPosition:
self.scrabbleScanViewPlugin.cutoutRect.origin.y +
self.scrabbleScanViewPlugin.cutoutRect.size.height +
self.scrabbleScanViewPlugin.frame.origin.y +
120];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.scrabbleScanViewPlugin stopAndReturnError:nil];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found scanning will stop automatically (you can change this behaviour
with cancelOnResult:). When the user dismisses self.identificationView this
method will get called again.
*/
- (void)startAnyline {
NSError *error;
BOOL success = [self.scrabbleScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
NSAssert(success, @"Start Scanning Error: %@", error.debugDescription);
}
self.startTime = CACurrentMediaTime();
}
- (void)stopAnyline {
if (self.scrabbleScanPlugin.isRunning) {
[self.scrabbleScanViewPlugin stopAndReturnError:nil];
}
}
#pragma mark -- AnylineOCRModuleDelegate
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result {
[self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.scrabbleScanViewPlugin completion:^{
[self stopAnyline];
ALScrabbleViewController *vc = [[ALScrabbleViewController alloc] init];
[vc setResult:result.result];
[self.navigationController pushViewController:vc animated:YES];
}];
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{
if ([info.variableName isEqualToString:@"$brightness"]) {
[self updateBrightness:[info.value floatValue] forModule:self.scrabbleScanViewPlugin];
}
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin runSkipped:(ALRunSkippedReason *)runSkippedReason {
//Handle run skipped reasons here:
switch (runSkippedReason.reason) {
case ALRunFailureResultNotValid:
break;
case ALRunFailureConfidenceNotReached:
break;
case ALRunFailureNoLinesFound:
break;
case ALRunFailureNoTextFound:
break;
case ALRunFailureUnkown:
break;
default:
break;
}
}
@end
|
AnylineOCR Plugin
LINE
: Record Numbers1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | {
"camera": {
"captureResolution": "720"
},
"flash": {
"mode": "manual",
"alignment": "bottom_right",
"imageOn": "flash_on",
"imageOff": "flash_off"
},
"viewPlugin": {
"plugin" : {
"id" : "OCR_RECORD",
"ocrPlugin" : {
"ocrConfig": {
"scanMode" : "LINE",
"languages" : ["eng_no_dict.traineddata", "deu.traineddata"],
"charWhitelist": "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.",
"minCharHeight":15,
"maxCharHeight":70,
"minConfidence": 75,
"removeSmallContours":false
}
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"maxHeightPercent": "80%",
"alignment": "center",
"width": 340,
"ratioFromSize": {
"width": 4,
"height": 1
},
"strokeWidth": 2,
"cornerRadius": 10,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"animationDuration": 400,
"style": "contour_point",
"strokeWidth": 2,
"strokeColor": "0099FF",
"fillColor": "220099FF",
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true
},
"cancelOnResult": true
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.ocr.OcrScanResult;
import io.anyline.plugin.ocr.OcrScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanRecordActiviy extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("record_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
OcrScanViewPlugin scanViewPlugin = (OcrScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<OcrScanResult>() {
@Override
public void onResult(OcrScanResult anylineOcrResult) {
String result = anylineOcrResult.getResult();
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #import "ALRecordNumberScanViewController.h"
#import <Anyline/Anyline.h>
#import "ALBaseViewController.h"
#import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALAppDemoLicenses.h"
// This is the license key for the examples project used to set up Aynline below
NSString * const kRecordNumberLicenseKey = kDemoAppLicenseKey;
// The controller has to conform to <AnylineOCRModuleDelegate> to be able to receive results
@interface ALRecordNumberScanViewController ()<ALOCRScanPluginDelegate, ALInfoDelegate>
// The Anyline plugin used for OCR
@property (nonatomic, strong) ALOCRScanViewPlugin *recordScanViewPlugin;
@property (nonatomic, strong) ALOCRScanPlugin *recordScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@end
@implementation ALRecordNumberScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"Record Number";
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kVoucherCodeLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
ALOCRConfig *config = [[ALOCRConfig alloc] init];
config.charHeight = ALRangeMake(22, 105);
config.charWhiteList = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.";
config.minConfidence = 70;
config.validationRegex = @"^([A-Z]+\\s*-*\\s*)?[0-9A-Z-\\s\\.]{3,}$";
config.scanMode = ALLine;
NSError *error = nil;
self.recordScanPlugin = [[ALOCRScanPlugin alloc] initWithPluginID:@"ANYLINE_OCR"
delegate:self
ocrConfig:config
error:&error];
NSAssert(self.recordScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.recordScanPlugin addInfoDelegate:self];
NSString *confPath = [[NSBundle mainBundle] pathForResource:@"record_number_config" ofType:@"json"];
ALScanViewPluginConfig *scanViewPluginConfig = [ALScanViewPluginConfig configurationFromJsonFilePath:confPath];
self.recordScanViewPlugin = [[ALOCRScanViewPlugin alloc] initWithScanPlugin:self.recordScanPlugin
scanViewPluginConfig:scanViewPluginConfig];
NSAssert(self.recordScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.recordScanViewPlugin];
// After setup is complete we add the module to the view of this view controller
[self.view addSubview:self.scanView];
[self.view sendSubviewToBack:self.scanView];
//Start Camera:
[self.scanView startCamera];
[self startListeningForMotion];
self.controllerType = ALScanHistoryRecordNumber;
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// We use this subroutine to start Anyline. The reason it has its own subroutine is
// so that we can later use it to restart the scanning process.
[self startAnyline];
//Update Position of Warning Indicator
[self updateWarningPosition:
self.recordScanViewPlugin.cutoutRect.origin.y +
self.recordScanViewPlugin.cutoutRect.size.height +
self.recordScanViewPlugin.frame.origin.y +
120];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.recordScanViewPlugin stopAndReturnError:nil];
}
/*
This method is used to tell Anyline to start scanning. It gets called in
viewDidAppear to start scanning the moment the view appears. Once a result
is found scanning will stop automatically (you can change this behaviour
with cancelOnResult:). When the user dismisses self.identificationView this
method will get called again.
*/
- (void)startAnyline {
NSError *error;
BOOL success = [self.recordScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
NSAssert(success, @"Start Scanning Error: %@", error.debugDescription);
}
self.startTime = CACurrentMediaTime();
}
#pragma mark -- AnylineOCRModuleDelegate
/*
This is the main delegate method Anyline uses to report its results
*/
- (void)anylineOCRScanPlugin:(ALOCRScanPlugin *)anylineOCRScanPlugin didFindResult:(ALOCRResult *)result {
[self anylineDidFindResult:result.result barcodeResult:@"" image:result.image scanPlugin:anylineOCRScanPlugin viewPlugin:self.recordScanViewPlugin completion:^{
ALBaseViewController *vc = [[ALBaseViewController alloc] init];
vc.result = result.result;
NSString *url = [NSString stringWithFormat:@"https://www.google.at/search?q=\"%@\" site:discogs.com OR site:musbrainz.org OR site:allmusic.com", result.result];
[vc startWebSearchWithURL:url];
[self.navigationController pushViewController:vc animated:YES];
}];
}
- (void)anylineScanPlugin:(ALAbstractScanPlugin *)anylineScanPlugin reportInfo:(ALScanInfo *)info{
if ([info.variableName isEqualToString:@"$brightness"]) {
[self updateBrightness:[info.value floatValue] forModule:self.recordScanViewPlugin];
}
}
@end
|
Barcode Plugin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | {
"camera": {
"captureResolution": "1080p"
},
"flash": {
"mode": "auto",
"alignment": "bottom_right"
},
"viewPlugin": {
"plugin": {
"id": "Barcode_ID",
"barcodePlugin": {
}
},
"cutoutConfig": {
"style": "rect",
"maxWidthPercent": "80%",
"maxHeightPercent": "80%",
"alignment": "center",
"ratioFromSize": {
"width": 100,
"height": 80
},
"strokeWidth": 1,
"cornerRadius": 3,
"strokeColor": "FFFFFF",
"outerColor": "000000",
"outerAlpha": 0.3,
"feedbackStrokeColor": "0099FF"
},
"scanFeedback": {
"style": "rect",
"strokeColor": "0099FF",
"fillColor": "220099FF",
"animationDuration": 150,
"blinkOnResult": true,
"beepOnResult": true,
"vibrateOnResult": true
},
"cancelOnResult": true
}}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;
import io.anyline.plugin.ScanResultListener;
import io.anyline.plugin.barcode.BarcodeScanResult;
import io.anyline.plugin.barcode.BarcodeScanViewPlugin;
import io.anyline.view.ScanView;
import io.anyline.AnylineSDK;
public class ScanBarcodeActivity extends Activity {
private ScanView scanView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anyline_scan_view);
scanView = findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
try {
scanView.init("barcode_view_config.json");
} catch (Exception e) {
e.printStackTrace();
}
BarcodeScanViewPlugin scanViewPlugin = (BarcodeScanViewPlugin) scanView.getScanViewPlugin();
scanViewPlugin.addScanResultListener(new ScanResultListener<BarcodeScanResult>() {
@Override
public void onResult(BarcodeScanResult result) {
Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_LONG).show();
}
});
}
@Override
protected void onResume() {
super.onResume();
scanView.start();
}
@Override
protected void onPause() {
super.onPause();
scanView.stop();
scanView.releaseCameraInBackground();
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | // This is the license key for the examples project used to set up Anyline below
NSString * const kBarcodeScanLicenseKey = kDemoAppLicenseKey;
// The controller has to conform to <AnylineBarcodeModuleDelegate> to be able to receive results
@interface ALMultiformatBarcodeScanViewController() <ALBarcodeScanPluginDelegate, ALScanViewPluginDelegate>
// The Anyline plugin used to scan barcodes
@property (nonatomic, strong) ALBarcodeScanPlugin *barcodeScanPlugin;
@property (nonatomic, strong) ALBarcodeScanViewPlugin *barcodeScanViewPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
// A debug label to show scanned results
@property (nonatomic, strong) UILabel *resultLabel;
@end
@implementation ALMultiformatBarcodeScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = @"Barcodes";
CGRect frame = [self scanViewFrame];
NSError *licenseError = nil;
//Initialize Anyline
[AnylineSDK setupWithLicenseKey:kBarcodeScanLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
NSLog(@" *** Error: setup error: %@", licenseError);
}
//Add Barcode Scan Plugin (Scan Process)
NSError *error = nil;
self.barcodeScanPlugin = [[ALBarcodeScanPlugin alloc] initWithPluginID:@"BARCODE" delegate:self error:&error];
NSAssert(self.barcodeScanPlugin, @"Setup Error: %@", error.debugDescription);
//Set Barcode Formats
[self.barcodeScanPlugin setBarcodeFormatOptions:@[kCodeTypePDF417]];
//Add Barcode Scan View Plugin (Scan UI)
self.barcodeScanViewPlugin = [[ALBarcodeScanViewPlugin alloc] initWithScanPlugin:self.barcodeScanPlugin];
NSAssert(self.barcodeScanViewPlugin, @"Setup Error: %@", error.debugDescription);
[self.barcodeScanViewPlugin addScanViewPluginDelegate:self];
//Add ScanView (Camera and Flashbutton)
self.scanView = [[ALScanView alloc] initWithFrame:frame scanViewPlugin:self.barcodeScanViewPlugin];
[self.view addSubview:self.scanView];
[self.scanView startCamera];
self.barcodeScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO;
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView}]];
id topGuide = self.topLayoutGuide;
[[self view] addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topGuide]-0-[scanView]|" options:0 metrics:nil views:@{@"scanView" : self.scanView, @"topGuide" : topGuide}]];
// The resultLabel is used as a debug view to see the scanned results. We set its text
// in anylineBarcodeModuleView:didFindScanResult:atImage below
self.resultLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 100, self.view.frame.size.width, 50)];
self.resultLabel.textAlignment = NSTextAlignmentCenter;
self.resultLabel.textColor = [UIColor whiteColor];
self.resultLabel.font = [UIFont fontWithName:@"HelveticaNeue-UltraLight" size:35.0];
self.resultLabel.adjustsFontSizeToFitWidth = YES;
[self.view addSubview:self.resultLabel];
self.barcodeScanPlugin.multiBarcode = YES;
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self startPlugin:self.barcodeScanViewPlugin];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.barcodeScanViewPlugin stopAndReturnError:nil];
}
#pragma mark -- AnylineBarcodeModuleDelegate
- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin didFindResult:(ALBarcodeResult *)scanResult {
ALBarcodeResult * result = scanResult;
self.resultLabel.text = [result firstObject].value;
}
// This is called every frame
- (void)anylineBarcodeScanPlugin:(ALBarcodeScanPlugin *)anylineBarcodeScanPlugin scannedBarcodes:(ALBarcodeResult*)scanResult {
NSLog(@"Visible barcodes: %@", scanResult.result);
}
@end
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | using Anyline.SDK.Models;
using Anyline.SDK.Plugins;
using Anyline.SDK.Plugins.Barcode;
using Anyline.SDK.Util;
using Anyline.SDK.ViewPlugins;
using Anyline.SDK.Views;
using Anyline_Windows_UWP_Examples.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Foundation;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;
namespace Anyline_Windows_UWP_Examples
{
/// <summary>
/// This page is used to setup the plugin, open the camera and start scanning
/// it has to implement the IScanResultListener for each Plugin that will be used
/// </summary>
public sealed partial class ScanPage : Page, IScanResultListener<BarcodeScanResult>
{
string myLicenseKey = "INSERT LICENSE KEY HERE";
protected override async void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// register camera events
AnylineScanView.CameraView.CameraOpened += CameraView_CameraOpened;
AnylineScanView.CameraView.CameraClosed += CameraView_CameraClosed;
// register visibility changed event
Window.Current.VisibilityChanged += Current_VisibilityChanged;
// make sure the license is initalized (needs only to be done once in the app lifetime)
AnylineSDK.Init(myLicenseKey);
// initialize Anyline
await AnylineScanView.InitAsync("Assets/myconfig.json");
// attach the result listener to the ScanViewPlugin to receive scanning results
(AnylineScanView.ScanViewPlugin as BarcodeScanViewPlugin)?.AddScanResultListener(this);
// opens the camera
AnylineScanView.StartCamera();
}
private async void Current_VisibilityChanged(object sender, Windows.UI.Core.VisibilityChangedEventArgs args)
{
if (AnylineScanView == null) return;
if (args.Visible == false)
{
await AnylineScanView.StopCameraAsync();
}
if (args.Visible == true)
{
AnylineScanView.StartCamera();
}
}
private void CameraView_CameraOpened(object sender, Size args)
{
AnylineScanView.StartScanning();
}
private void CameraView_CameraClosed(object sender, bool success)
{
AnylineScanView.StopScanning();
}
public void OnResult(BarcodeScanResult result)
{
Debug.WriteLine($"(APP) Scan result: {result.Result}");
}
}
}
|
Document Plugin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | {
"captureResolution":"720p",
"pictureResolution":"1080p",
"cutout": {
"style": "rect",
"maxWidthPercent": "100%",
"maxHeightPercent": "100%",
"width": 720,
"ratioFromSize": {
"width": 10,
"height": 15
},
"alignment": "center",
"strokeWidth": 2,
"cornerRadius": 0,
"strokeColor": "00000000"
},
"flash": {
"mode": "manual",
"alignment": "bottom_left",
"offset": {
"x": 10,
"y": 0
}
},
"beepOnResult": true,
"vibrateOnResult": true,
"blinkAnimationOnResult": true,
"cancelOnResult": false
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | package io.anyline.examples.document;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;
import at.nineyards.anyline.camera.CameraController;
import at.nineyards.anyline.camera.CameraOpenListener;
import at.nineyards.anyline.models.AnylineImage;
import at.nineyards.anyline.modules.AnylineBaseModuleView;
import io.anyline.examples.R;
import io.anyline.examples.ScanActivity;
import io.anyline.examples.ScanModuleEnum;
import io.anyline.plugin.ScanResult;
import io.anyline.plugin.document.DocumentScanResultListener;
import io.anyline.plugin.document.DocumentScanViewPlugin;
import io.anyline.view.BaseScanViewConfig;
import io.anyline.view.ScanView;
import io.anyline.view.ScanViewPluginConfig;
import io.anyline.AnylineSDK;
/**
* Example activity for the Anyline-Document-Detection-Module
*/
public class ScanDocumentActivity extends AppCompatActivity implements CameraOpenListener {
private static final String TAG = ScanDocumentActivity.class.getSimpleName();
private ScanView documentScanView;
private Toast notificationToast;
private ImageView imageViewResult;
private ProgressDialog progressDialog;
private ImageView imageViewFull;
private List<PointF> lastOutline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLayoutInflater().inflate(R.layout.document_scan_view, (ViewGroup) findViewById(R.id.scan_view_placeholder));
imageViewFull = (ImageView) findViewById(R.id.image_result);
imageViewResult = (ImageView) findViewById(R.id.full_image);
documentScanView = (ScanView) findViewById(R.id.scan_view);
// This must be called before doing anything Anyline-related!
// Try/Catch this to check whether or not your license key is valid!
try {
AnylineSDK.init(getString(getString(R.string.anyline_license_key)), this);
} catch (LicenseException e) {
// handle exception
}
// add a camera open listener that will be called when the camera is opened or an error occurred
// this is optional (if not set a RuntimeException will be thrown if an error occurs)
documentScanView.setCameraOpenListener(this);
//init the scanViewPluginConfig
ScanViewPluginConfig documentScanViewPluginConfig = new ScanViewPluginConfig(getApplicationContext(), "document_view_config.json");
//init the Document Scan View Plugin
final DocumentScanViewPlugin documentScanViewPlugin = new DocumentScanViewPlugin(getApplicationContext(), documentScanViewPluginConfig, "Document");
//init the base config for camera and flash
BaseScanViewConfig documentBaseScanViewconfig = new BaseScanViewConfig(getApplicationContext(), "document_view_config.json");
//set the base config to the scan view
documentScanView.setScanViewConfig(documentBaseScanViewconfig);
//set the scan view plugin to the scan view
documentScanView.setScanViewPlugin(documentScanViewPlugin);
//set cancel on result on true
documentScanViewPlugin.getScanViewPluginConfig().setCancelOnResult(true);
documentScanViewPlugin.cancelOnResult();
documentScanViewPlugin.addScanResultListener(new DocumentScanResultListener() {
@Override
public void onPreviewProcessingSuccess(AnylineImage anylineImage) {
notificationToast = Toast.makeText(ScanDocumentActivity.this, "Scanning full document. Please hold " +
"still", Toast.LENGTH_LONG);
notificationToast.show();
showToast(getString(R.string.document_preview_success));
}
@Override
public void onPreviewProcessingFailure(DocumentScanViewPlugin.DocumentError error) {
// this is called on any error while processing the document image
// Note: this is called every time an error occurs in a run, so that might be quite often
// An error message should only be presented to the user after some time
Log.d("Callback", "onPictureProcessingFailure: " + error.name());
}
@Override
public void onPictureProcessingFailure(DocumentScanViewPlugin.DocumentError error) {
// handle an error while processing the full picture here
// the preview will be restarted automatically
String text = getString(R.string.document_picture_error);
switch (error) {
case DOCUMENT_NOT_SHARP:
text += getString(R.string.document_error_not_sharp);
break;
case DOCUMENT_SKEW_TOO_HIGH:
text += getString(R.string.document_error_skew_too_high);
break;
case DOCUMENT_OUTLINE_NOT_FOUND:
text += getString(R.string.document_error_outline_not_found);
break;
case GLARE_DETECTED:
text += getString(R.string.document_error_glare_detected);
break;
case IMAGE_TOO_DARK:
text += getString(R.string.document_error_too_dark);
break;
}
showToast(text);
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
AnylineImage image = documentScanViewPlugin.getCurrentFullImage();
if (image != null) {
File outDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "error");
outDir.mkdir();
File outFile = new File(outDir, "" + System.currentTimeMillis() + error.name() + ".jpg");
Log.d(TAG, "saved image to: " + outFile.getAbsolutePath());
try {
image.save(outFile, 100);
Log.d(TAG, "error image saved to " + outFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
image.release();
}
}
@Override
public void onTakePictureSuccess() {
progressDialog = ProgressDialog.show(ScanDocumentActivity.this, "Processing", "Processing the picture" +
". Please wait", true);
if (notificationToast != null) {
notificationToast.cancel();
}
}
@Override
public void onTakePictureError(Throwable error) {
Log.d("Callback", "onTakePictureError: " + error.getMessage());
}
@Override
public void onPictureTransformed(AnylineImage transformedImage) {
Log.d("Callback", "onPictureTransformed");
}
@Override
public void onPictureTransformError(DocumentScanViewPlugin.DocumentError error) {
Log.d("Callback", "onPictureTransformError: " + error.name());
}
@Override
public void onPictureCornersDetected(AnylineImage fullFrame, List corners) {
Log.d("Callback", "onPictureCornersDetected");
}
@Override
public boolean onDocumentOutlineDetected(List rect, boolean documentShapeAndBrightnessValid) {
lastOutline = rect;
return true;
}
@Override
public void onResult(ScanResult result) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
// handle the result document images here
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
AnylineImage transformedImage = (AnylineImage) result.getResult();
AnylineImage fullFrame = result.getFullImage();
showToast(getString(R.string.document_picture_success));
// show the picture on the screen
displayPicture(transformedImage);
/**
* IMPORTANT: cache provided frames here, and release them at the end of this onResult. Because
* keeping them in memory (e.g. setting the full frame to an ImageView)
* will result in a OutOfMemoryError soon. This error is reported in {@link #onTakePictureError
* (Throwable)}
*
* Use a DiskCache http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#disk-cache
* for example
*
*/
File outDir = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "ok");
outDir.mkdir();
File outFile = new File(outDir, "" + System.currentTimeMillis() + ".jpg");
try {
transformedImage.save(outFile, 100);
showToast("image saved to " + outFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
// release the images
transformedImage.release();
fullFrame.release();
}
});
}
/**
* Performs an animation after the final image was successfully processed. This is just an example.
*
* @param transformedImage The transformed final image
*/
private void displayPicture(AnylineImage transformedImage) {
imageViewResult.setImageBitmap(Bitmap.createScaledBitmap(transformedImage.getBitmap(), imageViewResult.getWidth(), imageViewResult.getHeight(), false));
imageViewResult.setVisibility(View.VISIBLE);
imageViewResult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
resetScanning();
}
});
}
@Override
protected AnylineBaseModuleView getScanView() {
return null;
}
private void showToast(String text) {
try {
notificationToast.setText(text);
} catch (Exception e) {
notificationToast = Toast.makeText(this, text, Toast.LENGTH_LONG);
}
notificationToast.show();
}
@Override
protected void onResume() {
super.onResume();
//start the actual scanning
documentScanView.start();
}
@Override
protected void onPause() {
super.onPause();
//stop the scanning
documentScanView.stop();
//release the camera (must be called in onPause, because there are situations where
// it cannot be auto-detected that the camera should be released)
documentScanView.releaseCameraInBackground();
}
@Override
public void onCameraOpened(CameraController cameraController, int width, int height) {
//the camera is opened async and this is called when the opening is finished
Log.d(TAG, "Camera opened successfully. Frame resolution " + width + " x " + height);
}
@Override
public void onCameraError(Exception e) {
//This is called if the camera could not be opened.
// (e.g. If there is no camera or the permission is denied)
// This is useful to present an alternative way to enter the required data if no camera exists.
throw new RuntimeException(e);
}
@Override
protected ScanModuleEnum.ScanModule getScanModule() {
return ScanModuleEnum.ScanModule.DOCUMENT;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if(imageViewResult.getVisibility() == View.VISIBLE){
resetScanning();
}else {
onBackPressed();
}
return true;
}
return false;
}
@Override
public void onBackPressed() {
if(imageViewResult.getVisibility() == View.VISIBLE){
resetScanning();
}else {
super.onBackPressed();
overridePendingTransition(R.anim.fade_in, R.anim.activity_close_translate);
}
}
private void resetScanning(){
if(imageViewResult.getVisibility() == View.VISIBLE){
imageViewResult.setVisibility(View.GONE);
if(documentScanView.getScanViewPlugin() != null && !documentScanView.getScanViewPlugin().isRunning() ){
documentScanView.start();
}
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | #import "ALDocumentScanViewController.h"
#import <Anyline/Anyline.h>
#import "NSUserDefaults+ALExamplesAdditions.h"
#import "ALRoundedView.h"
#import "ALAppDemoLicenses.h"
NSString * const kDocumentScanLicenseKey = kDemoAppLicenseKey;
@class AnylineDocumentModuleView;
@interface ALDocumentScanViewController () <ALDocumentScanPluginDelegate, ALInfoDelegate, ALDocumentInfoDelegate>
// The Anyline plugins used for Document
@property (nonatomic, strong) ALDocumentScanViewPlugin *documentScanViewPlugin;
@property (nonatomic, strong) ALDocumentScanPlugin *documentScanPlugin;
@property (nullable, nonatomic, strong) ALScanView *scanView;
@property (nonatomic, strong) ALRoundedView *roundedView;
@property (nonatomic, assign) NSInteger showingLabel;
@end
@implementation ALDocumentScanViewController
/*
We will do our main setup in viewDidLoad. Its called once the view controller is getting ready to be displayed.
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
[super viewDidLoad];
// Set the background color to black to have a nicer transition
self.view.backgroundColor = [UIColor blackColor];
self.title = NSLocalizedString(@"Scan Document", @"Scan Document");
// Initializing the module. Its a UIView subclass. We set the frame to fill the whole screen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame = CGRectMake(frame.origin.x, frame.origin.y + self.navigationController.navigationBar.frame.size.height, frame.size.width, frame.size.height - self.navigationController.navigationBar.frame.size.height);
NSError *licenseError = nil;
//Initialize the Anyline License
[AnylineSDK setupWithLicenseKey:kDocumentScanLicenseKey error:&licenseError];
if (licenseError) {
//Handle errors here
}
NSError *error = nil;
self.documentScanPlugin = [[ALDocumentScanPlugin alloc] initWithPluginID:@"DOCUMENT" delegate:self error:&error];;
NSAssert(self.documentScanPlugin, @"Setup Error: %@", error.debugDescription);
[self.documentScanPlugin addInfoDelegate:self];
[self.documentScanPlugin setDocumentRatios:@[@(ALDocumentRatioLetterPortrait), @(ALDocumentRatioLetterLandscape)]];
self.documentScanPlugin.maxDocumentRatioDeviation = @(0.15);
self.documentScanViewPlugin = [[ALDocumentScanViewPlugin alloc] initWithScanPlugin:self.documentScanPlugin];
NSAssert(self.documentScanViewPlugin, @"Setup Error: %@", error.debugDescription);
self.scanView = [[ALScanView alloc] initWithFrame:frame
scanViewPlugin:self.documentScanViewPlugin
cameraConfig:[ALCameraConfig defaultDocumentCameraConfig]
flashButtonConfig:[ALFlashButtonConfig defaultFlashConfig]];
// Enable PostProcessing
[self.documentScanPlugin setPostProcessingEnabled:YES];
// Disable justDetectCornersIfPossible
self.documentScanPlugin.justDetectCornersIfPossible = NO;
[self.documentScanPlugin enableReporting:[NSUserDefaults AL_reportingEnabled]];
self.controllerType = ALScanHistoryDocument;
self.documentScanViewPlugin.translatesAutoresizingMaskIntoConstraints = NO;
// After setup is complete we add the module to the view of this view controller
[self.view addSubview:self.scanView];
// Start Camera:
[self.scanView startCamera];
[self.view sendSubviewToBack:self.scanView];
[self startListeningForMotion];
// This view notifies the user of any problems that occur while he is scanning
self.roundedView = [[ALRoundedView alloc] initWithFrame:CGRectMake(20, 115, self.view.bounds.size.width - 40, 30)];
self.roundedView.fillColor = [UIColor colorWithRed:98.0/255.0 green:39.0/255.0 blue:232.0/255.0 alpha:0.6];
self.roundedView.textLabel.text = @"";
self.roundedView.alpha = 0;
[self.view addSubview:self.roundedView];
}
/*
This method will be called once the view controller and its subviews have appeared on screen
*/
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
/*
This is the place where we tell Anyline to start receiving and displaying images from the camera.
Success/error tells us if everything went fine.
*/
NSError *error;
BOOL success = [self.documentScanViewPlugin startAndReturnError:&error];
if( !success ) {
// Something went wrong. The error object contains the error description
[[[UIAlertView alloc] initWithTitle:@"Start Scanning Error"
message:error.debugDescription
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
}
//Update Position of Warning Indicator
[self updateWarningPosition:
self.documentScanViewPlugin.cutoutRect.origin.y +
self.documentScanViewPlugin.cutoutRect.size.height +
self.documentScanViewPlugin.frame.origin.y - 100];
}
/*
Cancel scanning to allow the module to clean up
*/
- (void)viewWillDisappear:(BOOL)animated {
[self.documentScanViewPlugin stopAndReturnError:nil];
}
#pragma mark -- AnylineDocumentModuleDelegate
/*
This is the main delegate method Anyline uses to report its scanned codes
*/
- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin
hasResult:(UIImage *)transformedImage
fullImage:(UIImage *)fullFrame
documentCorners:(ALSquare *)corners {
UIViewController *viewController = [[UIViewController alloc] init];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:viewController.view.bounds];
imageView.center = CGPointMake(imageView.center.x, imageView.center.y + 30);
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.image = transformedImage;
[viewController.view addSubview:imageView];
[self.navigationController pushViewController:viewController animated:YES];
}
/*
This method receives errors that occured during the scan.
*/
- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin
reportsPictureProcessingFailure:(ALDocumentError)error {
[self showUserLabel:error];
}
/*
This method receives errors that occured during the scan.
*/
- (void)anylineDocumentScanPlugin:(ALDocumentScanPlugin *)anylineDocumentScanPlugin
reportsPreviewProcessingFailure:(ALDocumentError)error {
[self showUserLabel:error];
}
/**
* Crops an arbitrary rectangle (e.g. trapezoid) of the input image and perspectively transforms it to a rectangle (e.g. square).
* After the transformation is complete the result delegate anylineDocumentScanPlugin:hasResult:fullImage:documentCorners will be triggered.
* In any case call [AnylineDocumentModuleView cancelScanningAndReturnError:] before using this method.
*
* Return value indicating the success / failure of the call.
*
*
*/
- (BOOL)transformImageWithSquare:(ALSquare *)square
image:(UIImage *)image
error:(NSError * *)error {
[self.scanViewPlugin transformImageWithSquare:square image:image error:&error];
}
- (BOOL)transformALImageWithSquare:(ALSquare *)square
image:(ALImage *)image
error:(NSError * *)error {
[self.scanViewPlugin transformALImageWithSquare:square image:image error:&error];
}
/**
* A manual picture will be taken. Anyline tries to detected any document corners and will report the result
* with the delegate method anylineDocumentModuleView:detectedPictureCorners:inImage:
*/
- (BOOL)triggerPictureCornerDetectionAndReturnError:(NSError **)error {
[self.documentModuleView triggerPictureCornerDetectionAndReturnError:&error];
}
#pragma mark -- Helper Methods
/*
Shows a little round label at the bottom of the screen to inform the user what happended
*/
- (void)showUserLabel:(ALDocumentError)error {
NSString *helpString = nil;
switch (error) {
case ALDocumentErrorNotSharp:
helpString = @"Document not Sharp";
break;
case ALDocumentErrorSkewTooHigh:
helpString = @"Wrong Perspective";
break;
case ALDocumentErrorImageTooDark:
helpString = @"Too Dark";
break;
case ALDocumentErrorShakeDetected:
helpString = @"Shake";
break;
default:
break;
}
//Display Error to indicate what the User should do.
}
@end
|
Tutorials and How To Guides
You can check more tutorials on our Youtube channel at https://www.youtube.com/playlist?list=PLFr-jBATSsLyH1PbsVc3pWsBegbyUI8bx