【问题标题】:Implementing barcode scanner in angular 4 application for android phone在 Android 手机的 Angular 4 应用程序中实现条码扫描器
【发布时间】:2018-04-17 11:45:33
【问题描述】:

我喜欢在我的 Angular 4 应用程序中实现条形码扫描模块。 我正在使用 ngx-barcode npm 模块来生成运行良好的条形码。

我的项目要求也是扫描,所以如果有人知道如何使用安卓相机扫描条形码将是一个很大的帮助。

【问题讨论】:

标签: barcode scanning


【解决方案1】:

[QuaggaJS][1] 是一个完全用 JavaScript 编写的条码扫描器,支持实时定位和解码各种类型的条码,例如EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5, 2of5, CODE 93 and CODABAR。该库还能够使用 getUserMedia 直接访问用户的相机流。尽管代码依赖于繁重的图像处理,但即使是最近的智能手机也能够实时定位和解码条形码。

使用 QuaggaJS,[Angular example][2] 进行条码扫描

用于角度条码扫描器的 NPM Angular 模块: [1]:https://serratus.github.io/quaggaJS [2]:https://github.com/LaurentSouchet-Orange/Angular-readbarcode-quagga [3]:https://github.com/julienboulay/ngx-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: 2 }, // sane aspect ratios?
        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][3]

【讨论】:

  • 我已经提交了一个编辑请求,将最大纵横比从 100 更改为 2,因为 100 在 iOS 14+ 中会导致非常不正确的结果
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-23
相关资源
最近更新 更多