Implementing a barcode scanner in Angular 4

2019-09-21 18:45发布

问题:

I am trying to implement a barcode scanner using Angular 4, using this plugin - https://github.com/isonet/angular-barcode-scanner.

In my scanner.component.ts page I have;

    import { Component, OnInit} from '@angular/core';
    import 'angular-barcode-scanner';
...

In my app.module.ts file;

  ....
import { BarcodeScanner} from 'angular-barcode-scanner';

    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot(routes),
        LoginModule,
        SignupModule,
        DashboardModule,
        ReactiveFormsModule,
        BarcodeScanner
      ],
      providers: [
        DataService,
        TokenService
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

And then in my scanner.component.html file;

<barcode-scanner separator-char="separatorChar" trigger-char="triggerChar" scan-callback="scanCallback"
                trigger-callback="triggerCallback"></barcode-scanner>
        </div>
    </div>

However, I get the following errors in console

Uncaught ReferenceError: angular is not defined
    at Object.defineProperty.value (angular-barcode-scanner.js:1)
    at r (angular-barcode-scanner.js:1)
    at Object.defineProperty.value (angular-barcode-scanner.js:1)
    at angular-barcode-scanner.js:1
    at t (angular-barcode-scanner.js:1)
    at Object.<anonymous> (angular-barcode-scanner.js:1)
    at __webpack_require__ (bootstrap 0689b0e…:52)
    at Object.152 (bsElement.routes.ts:9)
    at __webpack_require__ (bootstrap 0689b0e…:52)
    at Object.413 (chart.module.ts:12)
    at __webpack_require__ (bootstrap 0689b0e…:52)
    at Object.153 (chart.component.ts:11)
    at __webpack_require__ (bootstrap 0689b0e…:52)
    at Object.155 (dashboard.component.ts:12)
    at __webpack_require__ (bootstrap 0689b0e…:52)
Object.defineProperty.value @ angular-barcode-scanner.js:1
r @ angular-barcode-scanner.js:1
Object.defineProperty.value @ angular-barcode-scanner.js:1
(anonymous) @ angular-barcode-scanner.js:1
t @ angular-barcode-scanner.js:1
(anonymous) @ angular-barcode-scanner.js:1
__webpack_require__ @ bootstrap 0689b0e…:52
152 @ bsElement.routes.ts:9
__webpack_require__ @ bootstrap 0689b0e…:52
413 @ chart.module.ts:12
__webpack_require__ @ bootstrap 0689b0e…:52
153 @ chart.component.ts:11
__webpack_require__ @ bootstrap 0689b0e…:52
155 @ dashboard.component.ts:12
__webpack_require__ @ bootstrap 0689b0e…:52
405 @ app.module.ts:40
__webpack_require__ @ bootstrap 0689b0e…:52
404 @ main.ts:12
__webpack_require__ @ bootstrap 0689b0e…:52
424 @ table.module.ts:12
__webpack_require__ @ bootstrap 0689b0e…:52
393 @ src async:7
__webpack_require__ @ bootstrap 0689b0e…:52
733 @ main.bundle.js:2545
__webpack_require__ @ bootstrap 0689b0e…:52
webpackJsonpCallback @ bootstrap 0689b0e…:23
(anonymous) @ main.bundle.js:1
bundle.js:19 Uncaught ReferenceError: ng is not defined
    at N (bundle.js:19)
    at VueComponent.ready (bundle.js:15)
    at VueComponent.LN.M._callHook (bundle.js:5)
    at VueComponent.z (bundle.js:5)
    at VueComponent.N (bundle.js:5)
    at VueComponent.M.$emit (bundle.js:5)
    at VueComponent.LN.M._callHook (bundle.js:5)
    at z (bundle.js:5)
    at VueComponent.M.$before (bundle.js:5)
    at CN.transition (bundle.js:6)
    at CN.mountComponent (bundle.js:6)
    at bundle.js:6
    at bundle.js:6
    at N (bundle.js:4)
    at ON.QN.M._resolveComponent (bundle.js:5)
N @ bundle.js:19
ready @ bundle.js:15
LN.M._callHook @ bundle.js:5
z @ bundle.js:5
N @ bundle.js:5
M.$emit @ bundle.js:5
LN.M._callHook @ bundle.js:5
z @ bundle.js:5
M.$before @ bundle.js:5
transition @ bundle.js:6
mountComponent @ bundle.js:6
(anonymous) @ bundle.js:6
(anonymous) @ bundle.js:6
N @ bundle.js:4
QN.M._resolveComponent @ bundle.js:5
resolveComponent @ bundle.js:6
setComponent @ bundle.js:6
bind @ bundle.js:6
CN._bind @ bundle.js:6
Gz @ bundle.js:4
(anonymous) @ bundle.js:4
M._compile @ bundle.js:5
M.$mount @ bundle.js:5
M._init @ bundle.js:4
Y.M._init @ bundle.js:19
ON @ bundle.js:5
(anonymous) @ bundle.js:3
zone.js:155 Uncaught TypeError: Cannot read property 'geAdapter' of undefined
    at WebSocket._ws.onopen (eval at M.exports (bundle.js:3), <anonymous>:97:46)
    at WebSocket.wrapFn [as _onopen] (zone.js:851)
    at ZoneDelegate.invokeTask (zone.js:262)
    at Zone.runTask (zone.js:151)
    at WebSocket.ZoneTask.invoke (zone.js:332)
_ws.onopen @ VM53541:97
wrapFn @ zone.js:851
ZoneDelegate.invokeTask @ zone.js:262
Zone.runTask @ zone.js:151
ZoneTask.invoke @ zone.js:332

Any help is appreciated.

回答1:

https://github.com/isonet/angular-barcode-scanner is an AngularJS(V1) App and you seem to be building Angular(V4 may be?) app. I don't think you can use <barcode-scanner> just like that.



回答2:

QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real-time localization and decoding of various types of barcodes such as EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5, 2of5, CODE 93 and CODABAR. The library is also capable of using getUserMedia to get direct access to the user's camera stream. Although the code relies on heavy image-processing even recent smartphones are capable of locating and decoding barcodes in real-time.

Using QuaggaJS, Angular example for barcode scanner

NPM Angular module for angular barcode scanner:

import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import Quagga from 'quagga';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  barcode = '';
  barcodeResult;
  configQuagga = {
    inputStream: {
      name: 'Live',
      type: 'LiveStream',
      target: '#inputBarcode',
      constraints: {
        width: { min: 640 },
        height: { min: 480 },
        aspectRatio: { min: 1, max: 100 },
        facingMode: 'environment', // or user
      },
      singleChannel: false // true: only the red color-channel is read
    },
    locator: {
      patchSize: 'medium',
      halfSample: true
    },
    locate: true,
    numOfWorkers: 4,
    decoder: {
      readers: ['code_128_reader']
    }
  };
  constructor(private ref: ChangeDetectorRef) { }

  ngOnInit() {
    console.log('Barcode: initialization');
  }

  testChangeValues() {
    this.barcode = 'Code-barres bidon : 0123456789';
  }

  startScanner() {
    this.barcode = '';
    this.ref.detectChanges();

    Quagga.onProcessed((result) => this.onProcessed(result));

    Quagga.onDetected((result) => this.logCode(result));

    Quagga.init(this.configQuagga, (err) => {
      if (err) {
        return console.log(err);
      }
      Quagga.start();
      console.log('Barcode: initialization finished. Ready to start');
    });


  }

  private onProcessed(result: any) {
    const drawingCtx = Quagga.canvas.ctx.overlay;
    const drawingCanvas = Quagga.canvas.dom.overlay;

    if (result) {
      if (result.boxes) {
        drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute('width'), 10), parseInt(drawingCanvas.getAttribute('height'), 10));
        result.boxes.filter(function (box) {
          return box !== result.box;
        }).forEach(function (box) {
          Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: 'green', lineWidth: 2 });
        });
      }

      if (result.box) {
        Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: '#00F', lineWidth: 2 });
      }

      if (result.codeResult && result.codeResult.code) {
        Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
      }
    }
  }

  private logCode(result) {
    const code = result.codeResult.code;
   
    if (this.barcode !== code) {
      this.barcode = 'Code-barres EAN : ' + code;
      this.barcodeResult=result.codeResult;
      this.ref.detectChanges();
      console.log(this.barcode);
      console.log(this.barcodeResult);

      // this.barcodeValue = result.codeResult.code;
      // this.barcodeResult=result.codeResult
      // console.log("this.barcodeValue",this.barcodeValue)

      console.log("JSON.stringify(result.codeResult)",JSON.stringify(result.codeResult))
      console.log("Result",result)
      console.log("JSON.stringify(result)",JSON.stringify(result))
      // console.log("this.barcodeResult",this.barcodeResult.json())
      Quagga.stop();
    }

  }

}
#interactive.viewport {
    position: relative;
    width: 100%;
    height: auto;
    overflow: hidden;
    text-align: center;
}

#interactive.viewport>canvas,
#interactive.viewport>video {
    max-width: 100%;
    width: 100%;
}

canvas.drawing,
canvas.drawingBuffer {
    position: absolute;
    left: 0;
    top: 0;
}
h1 {
    color: white;
    background-color: #ff6600;
    text-align: center;
    font-size: 20px;
    font-weight: bold;
    /* TODO style temporaire en attendant de migrer dans un autre composant */
    margin: auto !important;
    padding: 0px !important;
    height: 40px;
    line-height: 40px;
}
<div>
  <ngb-alert type="info" [dismissible]="false">
      <strong>Je scanne</strong> le code-barres pour voir les ODR.
  </ngb-alert>
</div>
<div *ngIf="barcode">
  <ngb-alert type="success" [dismissible]="false">
      {{ barcode }}
  </ngb-alert>
</div>

<button type="button" class="btn btn-warning" (click)="startScanner()">
  Démarrer le scan du code-barres
</button>

<div class="input-group">
 
  <div id="inputBarcode" style="position: static">
      <div id="interactive" class="viewport"></div>
  </div>
</div>

GitHub Reference Link