Как реализовать модуль распознавания MRZ в Angular с нуля

Dynamsoft Label Recognizer — это JavaScript MRZ SDK, который позволяет разработчикам создавать веб-приложения для распознавания паспортов, виз, удостоверений личности и проездных документов. Объединив Dynamsoft Label Recognizer и Dynamsoft Camera Enhancer, можно легко создавать приложения для распознавания MRZ в реальном времени с помощью камеры. Цель этой статьи — обернуть Dynamsoft Label Recognizer и Dynamsoft Camera Enhancer в модуль Angular, что сэкономит время разработчиков на создание приложений для распознавания MRZ с помощью Angular.

Пакет NPM

https://www.npmjs.com/package/ngx-mrz-sdk

Предварительные условия

  • Node.js
  • Angular CLI

    npm install -g @angular/cli
    
  • Подайте заявку на получение 30-дневного БЕСПЛАТНОГО лицензионного ключа Dynamsoft Label Recognizer

Шаги по созданию модуля распознавания МРЗ в Angular

Создайте проект библиотеки Angular

Мы используем Angular CLI для создания нового проекта Angular и добавления в него проекта библиотеки:

ng new angular-mrz-scanner
cd angular-mrz-scanner
ng generate library ngx-mrz-sdk
Войдите в полноэкранный режим Выйти из полноэкранного режима

Проект Angular app может быть использован для тестирования и отладки библиотечного проекта. Выполните следующие команды соответственно в двух терминалах, чтобы они работали вместе:

ng build ngx-mrz-sdk --watch
ng serve --ssl
Войти в полноэкранный режим Выйти из полноэкранного режима

Если обе команды скомпилированы успешно, мы можем сменить директорию на библиотечный проект и приступить к реализации модуля распознавания MRZ.

cd projects/ngx-mrz-sdk/src/lib
Войти в полноэкранный режим Выйти из полноэкранного режима

Установите Dynamsoft Label Recognizer и Dynamsoft Camera Enhancer

Добавьте dynamsoft-label-recognizer и dynamsoft-camera-enhancer в peerDependencies в файле package.json:

"peerDependencies": {
    "dynamsoft-camera-enhancer": "^3.0.1",
    "dynamsoft-label-recognizer": "^2.2.11"
  },
Вход в полноэкранный режим Выйдите из полноэкранного режима

Затем запустите npm install, чтобы загрузить эти два пакета.

Настройка лицензионного ключа и пути к ресурсам

Файл ngx-mrz-sdk.service.ts экспортирует глобальный доступный сервис, в котором мы можем установить лицензионный ключ Dynamsoft Label Recognizer и пути ресурсов Dynamsoft Camera Enhancer и Dynamsoft Label Recognizer.

import { Injectable, Optional } from '@angular/core';
import { LabelRecognizer } from 'dynamsoft-label-recognizer';
import { CameraEnhancer } from 'dynamsoft-camera-enhancer';

export class MrzSdkServiceConfig {
  licenseKey = '';
  dceResourcePath = '';
  dlrResourcePath = '';
}

@Injectable({
  providedIn: 'root'
})

export class NgxMrzSdkService {

  constructor(@Optional() config?: MrzSdkServiceConfig) { 
    if (config) { 
      LabelRecognizer.license = config.licenseKey;
      LabelRecognizer.engineResourcePath = config.dlrResourcePath;
      CameraEnhancer.engineResourcePath = config.dceResourcePath;
    }
  }
}

Вход в полноэкранный режим Выход из полноэкранного режима

Разбор данных MRZ

Поскольку строки MRZ распознаны, нам необходимо разобрать их и извлечь подробную информацию. Поскольку онлайн-демонстрация Dynamsoft содержит логику разбора, нам не нужно заново изобретать колесо. Создайте файл parser.ts, содержащий следующий код:

export class MrzParser {

    static parseTwoLines(line1: string, line2: string): any {
        let mrzInfo: any = {};
        let type = line1.substring(0, 1);
        if (!(/[I|P|V]/.test(type))) return false;
        if (type === 'P') {
            mrzInfo.type = 'PASSPORT (TD-3)';
        } 
        ...
        return mrzInfo;
    };

    static parseThreeLines(line1: string, line2: string, line3: string): any {
        let mrzInfo: any = {};
        let type = line1.substring(0, 1);
        if (!(/[I|P|V]/.test(type))) return false;
        mrzInfo.type = 'ID CARD (TD-1)';
        ...
        return mrzInfo;
    }

}
Вход в полноэкранный режим Выйти из полноэкранного режима

Показ результатов на оверлее

Чтобы обеспечить лучший пользовательский опыт, мы можем показать результаты на оверлее. Создайте файл overlay.ts для отображения результатов распознавания MRZ:

export class OverlayManager {
    overlay: HTMLCanvasElement | undefined;
    context: CanvasRenderingContext2D | undefined;

    initOverlay(overlay: HTMLCanvasElement): void {
        this.overlay = overlay;
        this.context = this.overlay.getContext('2d') as CanvasRenderingContext2D;
    }

    updateOverlay(width: number, height: number): void {
        if (this.overlay) {
            this.overlay.width = width;
            this.overlay.height = height;
            this.clearOverlay();
        }
    }

    clearOverlay(): void {
        if (this.context && this.overlay) {
            this.context.clearRect(0, 0, this.overlay.width, this.overlay.height);
            this.context.strokeStyle = '#ff0000';
            this.context.lineWidth = 5;
        }
    }

    drawOverlay(points: any, text: any): void {
        if (this.context) {
            this.context.beginPath();
            this.context.moveTo(points[0].x, points[0].y);
            this.context.lineTo(points[1].x, points[1].y);
            this.context.lineTo(points[2].x, points[2].y);
            this.context.lineTo(points[3].x, points[3].y);
            this.context.lineTo(points[0].x, points[0].y);
            this.context.stroke();

            this.context.font = '18px Verdana';
            this.context.fillStyle = '#ff0000';
            let x = [points[0].x, points[1].x, points[0].x, points[0].x];
            let y = [points[0].y, points[1].y, points[0].y, points[0].y];
            x.sort(function (a, b) {
                return a - b;
            });
            y.sort(function (a, b) {
                return b - a;
            });
            let left = x[0];
            let top = y[0];

            this.context.fillText(text, left, top);
        }
    }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Генерация компонентов MRZ Reader и MRZ Scanner

Выполним следующие команды для генерации двух компонентов: ngx-mrz-reader и ngx-mrz-scanner:

ng generate component ngx-mrz-reader --skip-import
ng generate component ngx-mrz-scanner --skip-import
Войти в полноэкранный режим Выход из полноэкранного режима
  • ngx-mrz-reader используется для сканирования MRZ из файлов изображений.

    <span id="loading-status" style="font-size:x-large" [hidden]="isLoaded">Loading Library...</span>
    <br />
    
    <input type="file" title="file" id="file" accept="image/*" (change)="onChange($event)" />
    
    <div id="imageview">
      <img id="image" alt=""/>
      <canvas id="overlay"></canvas>
    </div>
    
  • ngx-mrz-scanner используется для сканирования MRZ с камеры.

    <div id="mrz-scanner">
      <span id="loading-status" style="font-size:x-large" [hidden]="isLoaded">Loading Library...</span>
      <br />
    
      <div>
          <label for="videoSource">Video Source</label>
          <select id="videoSource" (change)="openCamera()"></select>
      </div>
    
      <div id="videoview">
          <div class="dce-video-container" id="videoContainer"></div>
          <canvas id="overlay"></canvas>
      </div>
    </div>
    

Оба они содержат свойства @Input и @Output. Свойства @Input используются для передачи конфигурации компонентам. Свойства @Output используются для передачи событий родительскому компоненту.

@Input() showOverlay: boolean;
@Output() result = new EventEmitter<any>();

constructor() {
  this.showOverlay = true;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Инициализируйте Dynamsoft Label Recognizer в методе ngOnInit:

ngOnInit(): void {
    this.overlayManager.initOverlay(document.getElementById('overlay') as HTMLCanvasElement);
    (async () => {
      LabelRecognizer.onResourcesLoaded = (resourcePath) => {
        this.isLoaded = true;
      };
      this.reader = await LabelRecognizer.createInstance();
      await this.reader.updateRuntimeSettingsFromString("MRZ");

    })();
  }
Вход в полноэкранный режим Выйти из полноэкранного режима

Чтобы распознать MRZ из файлов изображений, вызываем метод recognize().

this.reader.recognize(file).then((results: any) => {
  let txts: any = [];
  try {
    if (results.length > 0) {
      for (let result of results) {
        for (let line of result.lineResults) {
            txts.push(line.text);
            if (this.showOverlay) this.overlayManager.drawOverlay(line.location.points, line.text);
        }
      }

      let parsedResults = "";
      if (txts.length == 2) {
        parsedResults = MrzParser.parseTwoLines(txts[0], txts[1]);
      }
      else if (txts.length == 3) {
        parsedResults = MrzParser.parseThreeLines(txts[0], txts[1], txts[2]);
      }
      this.result.emit([txts.join('n'), parsedResults]);
    } else {
      this.result.emit(txts.join(''));
    }
  } catch (e) {
    alert(e);
  }
});
Вход в полноэкранный режим Выход из полноэкранного режима

Сканирование MRZ с камеры также является простым делом. Все, что нам нужно сделать, это связать Dynamsoft Label Recognizer с Dynamsoft Camera Enhancer и затем получить результаты распознавания MRZ из зарегистрированного обратного вызова.

this.cameraEnhancer = await CameraEnhancer.createInstance();
let uiElement = document.getElementById('videoContainer');
if (uiElement) {
  await this.cameraEnhancer.setUIElement(uiElement);
}

if (this.showOverlay) {
  await this.scanner.setImageSource(this.cameraEnhancer, { resultsHighlightBaseShapes: DrawingItem });
}
else {
  await this.scanner.setImageSource(this.cameraEnhancer, {});
}

this.scanner.onImageRead = (results: any) => {
  this.overlayManager.clearOverlay();
  let txts: any = [];
  try {
    if (results.length > 0) {
      for (let result of results) {
        for (let line of result.lineResults) {
          txts.push(line.text);
          if (this.showOverlay) this.overlayManager.drawOverlay(line.location.points, line.text);
        }
      }

      let parsedResults = "";
      if (txts.length == 2) {
        parsedResults = MrzParser.parseTwoLines(txts[0], txts[1]);
      }
      else if (txts.length == 3) {
        parsedResults = MrzParser.parseThreeLines(txts[0], txts[1], txts[2]);
      }
      this.result.emit([txts.join('n'), parsedResults]);
    } else {
      this.result.emit(txts.join(''));
    }
  } catch (e) {
    alert(e);
  }
};
this.cameraEnhancer.on("played", (playCallBackInfo: any) => {
  this.updateResolution();
});
await this.scanner.startScanning(true);
Вход в полноэкранный режим Выход из полноэкранного режима

Настройка *.module.ts

Файл ngx-mrz-sdk.module.ts используется для экспорта компонентов Angular и инициализации сервиса.

import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core';
import { NgxMrzReaderComponent } from './ngx-mrz-reader/ngx-mrz-reader.component';
import { NgxMrzScannerComponent } from './ngx-mrz-scanner/ngx-mrz-scanner.component';
import { MrzSdkServiceConfig } from './ngx-mrz-sdk.service';

@NgModule({
  declarations: [
    NgxMrzReaderComponent,
    NgxMrzScannerComponent
  ],
  imports: [
  ],
  exports: [
    NgxMrzReaderComponent,
    NgxMrzScannerComponent
  ]
})
export class NgxMrzSdkModule { 
  constructor(@Optional() @SkipSelf() parentModule?: NgxMrzSdkModule) {
    if (parentModule) {
      throw new Error(
        'GreetingModule is already loaded. Import it in the AppModule only');
    }
  }

  static forRoot(config: MrzSdkServiceConfig): ModuleWithProviders<NgxMrzSdkModule> {
    return {
      ngModule: NgxMrzSdkModule,
      providers: [
        { provide: MrzSdkServiceConfig, useValue: config }
      ]
    };
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Тестирование модуля распознавания МРЗ в Angular

  1. Установите пакет ngx-mrz-sdk.

    npm install ngx-mrz-sdk
    
  2. Создайте новый компонент Angular в проекте Angular:

    ng generate component mrz-scanner
    
  3. Включите <ngx-mrz-scanner> в файл mrz-scanner.component.html.

    <div id="mrzResult">
      {{mrzResult}}
    </div>
    
    <ngx-mrz-scanner
    (result)="onResultReady($event)"
    [showOverlay]="true"
    ></ngx-mrz-scanner>
    

    Внедрите сервис и реализуйте функцию обратного вызова MRZ в mrz-scanner.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { NgxMrzSdkService } from 'ngx-mrz-sdk';
    
    @Component({
      selector: 'app-mrz-scanner',
      templateUrl: './mrz-scanner.component.html',
      styleUrls: ['./mrz-scanner.component.css']
    })
    export class MrzScannerComponent implements OnInit {
      mrzResult: string = '';
      constructor(private mrzSdkService: NgxMrzSdkService) {
      }
    
      ngOnInit(): void {
      }
    
      // result = [originalValue, parsedValue]
      onResultReady(result: any): void {
        this.mrzResult = "";
        for (let i in result[1]) {
          this.mrzResult += i + ": " + result[1][i] + 'n';
        }
        // this.mrzResult = result[0];
      }
    }
    
  4. Установите лицензионный ключ и путь к ресурсам в app.module.ts:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { MrzReaderComponent } from './mrz-reader/mrz-reader.component';
    import { MrzScannerComponent } from './mrz-scanner/mrz-scanner.component';
    import { ProductListComponent } from './product-list/product-list.component';
    import { TopBarComponent } from './top-bar/top-bar.component';
    import { NgxMrzSdkModule } from 'ngx-mrz-sdk';
    
    @NgModule({
      declarations: [
        AppComponent,
        MrzReaderComponent,
        MrzScannerComponent,
        ProductListComponent,
        TopBarComponent,
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        NgxMrzSdkModule.forRoot({ 
          licenseKey: "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==", 
          dceResourcePath: "assets/dynamsoft-camera-enhancer", 
          dlrResourcePath: "assets/dynamsoft-label-recognizer"}),
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    
  5. Настройте путь к ресурсам в angular.json:

    "assets": [
        "src/favicon.ico",
        "src/assets",
        {
          "glob": "**/*",
          "input": "./node_modules/dynamsoft-label-recognizer/dist",
          "output": "assets/dynamsoft-label-recognizer"
        },
        {
          "glob": "**/*",
          "input": "./node_modules/dynamsoft-camera-enhancer/dist",
          "output": "assets/dynamsoft-camera-enhancer"
        }
      ],
    
  6. Запустите приложение сканера Angular MRZ:

    ng serve
    

Исходный код

https://github.com/yushulx/ngx-mrz-sdk

Оцените статью
devanswers.ru
Добавить комментарий