처음부터 Angular MRZ 인식 모듈을 구현하는 방법

Dynamsoft Label Recognizer은 개발자가 여권, Visa, ID 카드 및 여행 문서를 인식하는 웹 애플리케이션을 구축할 수 있도록 하는 JavaScript MRZ SDK입니다. Dynamsoft Label Recognizer와 Dynamsoft Camera Enhancer을 결합하면 카메라로 실시간 MRZ 인식 애플리케이션을 쉽게 구축할 수 있습니다. 이 기사는 Dynamsoft Label Recognizer 및 Dynamsoft Camera Enhancer를 Angular 모듈로 래핑하여 개발자가 Angular를 사용하여 MRZ 인식 애플리케이션을 구축하는 시간을 절약하는 것을 목표로 합니다.

NPM 패키지



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

전제 조건


  • Node.js

  • 각도 CLI

    npm install -g @angular/cli
    

  • 30-day FREE License key of Dynamsoft Label Recognizer

  • Angular MRZ 인식 모듈을 구축하는 단계



    Angular 라이브러리 프로젝트 비계



    Angular CLI를 사용하여 새 Angular 프로젝트를 만들고 여기에 라이브러리 프로젝트를 추가합니다.

    ng new angular-mrz-scanner
    cd angular-mrz-scanner
    ng generate library ngx-mrz-sdk
    


    Angular 앱 프로젝트는 라이브러리 프로젝트를 테스트하고 디버그하는 데 사용할 수 있습니다. 두 터미널에서 각각 다음 명령을 실행하여 함께 작동하도록 합니다.

    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-enhancerpeerDependenciespackage.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 온라인 데모에는 parsing logic이 포함되어 있으므로 바퀴를 다시 발명할 필요가 없습니다. 다음 코드를 포함하는 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 판독기 및 MRZ 스캐너 구성 요소 생성



    다음 명령을 실행하여 ngx-mrz-readerngx-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;
    }
    

    ngOnInit 메서드에서 Dynamsoft Label Recognizer 초기화:

    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 MRZ 인식 모듈 테스트


  • ngx-mrz-sdk 패키지를 설치합니다.

    npm install ngx-mrz-sdk
    


  • Angular 프로젝트에서 새 Angular 구성 요소를 만듭니다.

    ng generate component mrz-scanner
    

  • <ngx-mrz-scanner> 파일에 mrz-scanner.component.html를 포함합니다.

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

    서비스를 삽입하고 mrz-scanner.component.ts에서 MRZ 콜백 함수를 구현합니다.

    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];
      }
    }
    

  • 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 { }
    
    

  • 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"
        }
      ],
    


  • Angular MRZ 스캐너 애플리케이션을 실행합니다.

    ng serve
    



  • 소스 코드



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

    좋은 웹페이지 즐겨찾기