ZXing-js/browser returns a ChecksumError no matter what QR Code I use

358 Views Asked by At

I'm having an issue with ZXing-js. Its returning a ChecksumException no matter what QR Code I put into it. So its detecting the QRCode but throws an Exception. The following is my vuejs 2.0 code. Please help.

Almost all if this code works. Its just the reading of the QR code part that doesn't

  import { BarcodeFormat, DecodeHintType, NotFoundException, ChecksumException, FormatException } from '@zxing/library';

const ZXing = require('@zxing/browser');

Vue.component('qr_scanner_modal',{
    prop: [
          'videoSource'
          ],

    data: function ()
      {
      return {
            qr_error: null,
            qrcanvas: null,
            context: null,
            qrvideo:  null,
            hints: null,
            formats: null,
            videoSource: {},
            qr: null,
            selected_source: null,
            polling: null,
            localMediaStream: null,
            scanLineDirect: 'down',
            scanlineOffset: 0,
            qr_title: "",
            visible: false,
            focused: true,
            qr_result: ""
            };
      },
    mixins: [ focusMixin ],

    created: function ()
            {

            EventBus.$on('trigger-qrcode-scanner', (qrTitle) => this.show(qrTitle));
            },

    mounted: function ()
            {
            let self = this;

            this.$root.$on('bv::modal::show', () => this.$nextTick(() => this.mountQRReader()));
            },

    methods: {
            mountQRReader: function ()
                {
                const hints = new Map();


                const formats = [BarcodeFormat.QR_CODE, BarcodeFormat.DATA_MATRIX/*, ...*/];

                hints.set(DecodeHintType.POSSIBLE_FORMATS, formats);
                hints.set(DecodeHintType.TRY_HARDER, true);
                hints.set(DecodeHintType.CHARACTER_SET, 'UTF-8');
                hints.set(DecodeHintType.ALSO_INVERTED, true);

                this.qr = new ZXing.BrowserQRCodeReader(hints);


                this.qrcanvas = this.$refs['qrcanvas'];
                this.qrcanvas.width = 400;
                this.qrcanvas.height = 400;

                //     this.qrcanvas = this.$refs;
                console.log(this.$refs['qrcanvas']);

                this.context = this.$refs['qrcanvas'].getContext('2d');

                this.qrvideo = this.$refs['qrvideo'];

                navigator.getUserMedia = navigator.getUserMedia ||
                                        navigator.webkitGetUserMedia ||
                                        navigator.mozGetUserMedia ||
                                        navigator.msGetUserMedia;


                if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices)
                        {
                        this.qr_error = "This browser does not support MediaStreamTrack. Try Chrome.";
                        console.log("enumerateDevices() not supported.");
                        }

                else
                        {
                        this.qr_error = null;
                        }

                let self = this;

                navigator.mediaDevices
                        .enumerateDevices()
                        .then(function (sourceInfos)
                            {
                            let videosource = [];

                            for (var index = 0; index !== sourceInfos.length; index++)
                                    {
                                    var sourceInfo = sourceInfos[index];

                                    if (sourceInfo.kind === 'videoinput')
                                            {
                                            videosource.push({
                                                            id: sourceInfo.deviceId,
                                                            name: sourceInfo.label || 'Camera ' + index
                                                            });

                                            console.log(sourceInfo);
                                            console.log(videosource);
                                            }

                                    }

                            self.videoSource = videosource;
                            })

                        .catch(function (err)
                            {
                            console.log(err.name + ": " + err.message);
                            });
                },
            show: function (qrTitle)
                    {
                    console.log("Show modal called.");

                    this.qr_title = qrTitle + " - QR / Magstripe Reader";

                    this.$bvModal.show('qr_code_scanner');
                    },

            dismiss:  function()
                    {
                    this.stopScan();

                    this.$bvModal.hide('qr_code_scanner');
                    },

            selectSource: function (source)
                    {
                    this.selected_source = source;

                    let constraints = {
                            audio: false,
                            video: {
                                   facingMode: "environment",
                                   sourceId: source
                                   }
                            };


                    navigator.getUserMedia(constraints, this.startScan, this.scanError);
                    },

            read: function (value)
                    {
                    console.log('read callback called.');
                    console.log(value);


                    if (value !== null && value !== undefined)
                        {
                        this.qr_result = value.text;

                        EventBus.$emit('qr_code_returned', value.text);

                        this.stopScan();

                        return;
                        }


                    },

            startScan: function (stream)
                    {
                    this.qrvideo.srcObject = stream;

                    this.localMediaStream = stream;

                    this.qrvideo.play();

                    this.polling = setInterval(this.scan, 400);


                    },

            scanError: function (err)
                    {
                    if (err)
                        {
                        this.qr_error = err;
                        }
                    },

            stopScan: function ()
                    {
                    clearInterval(this.polling);

                    if (this.localMediaStream)
                        {
                        let track = this.localMediaStream.getVideoTracks();

                        track[0].stop();
                        }
                    },

            transposeRect: function  (width, height)
                    {
                    const rectWidth = width * 0.8;
                    const rectHeight = height * 0.8;

                    const xPos = (width - rectWidth) / 2;
                    const yPos = (height - rectHeight) / 2;
                    this.context.beginPath();
                    this.context.strokeStyle = 'red';
                    this.context.lineWidth = '3';
                    this.context.rect(  xPos,
                                        yPos,
                                        rectWidth,
                                        rectHeight);
                    this.context.stroke();

                    this.drawScanLine(yPos,
                                      xPos,
                                      xPos + rectWidth,
                                      yPos + rectHeight);
                    },

            drawScanLine: function (top, left, right, bottom)
                    {
                    if (this.scanLineDirect === 'down')
                        {
                        this.scanlineOffset = this.scanlineOffset + 4;
                        }

                    if (this.scanLineDirect === 'up')
                        {
                        this.scanlineOffset = this.scanlineOffset - 4;
                        }

                    if (top + this.scanlineOffset > bottom)
                        {
                        this.scanLineDirect = 'up';
                        this.scanlineOffset = this.scanlineOffset - 4;
                        }

                    if (top + this.scanlineOffset < top)
                        {
                        this.scanLineDirect = 'down';
                        this.scanlineOffset = this.scanlineOffset + 4;
                        }


                    this.context.beginPath();
                    this.context.strokeStyle = 'red';
                    this.context.lineWidth = '3';
                    this.context.moveTo(left, top + this.scanlineOffset);
                    this.context.lineTo(right, top + this.scanlineOffset);
                    this.context.closePath();
                    this.context.stroke();
                    },

            scan: async function ()
                    {
                    try
                        {
                        if (this.localMediaStream)
                            {
                            console.log("Scanning Video Feed.");


                            const width = this.qrcanvas.getAttribute('width');
                            const height = this.qrcanvas.getAttribute('height');

                            this.context.drawImage(this.qrvideo, 0, 0, width, height);

                            console.log("width: " + width);
                            console.log("height: " + height);


                            const code = await this.qr.decodeFromCanvas(this.qrcanvas);

                            //  const code = await this.qr.decode(this.qrcanvas);

                            this.read(code);

                            this.transposeRect(width, height);

                            }
                        }
                    catch(err)
                        {
                        if (err instanceof NotFoundException) {
                                console.log('No QR code found.')
                              }

                        if (err instanceof ChecksumException) {
                                console.log('A code was found, but it\'s read value was not valid.')
                              }

                        if (err instanceof FormatException) {
                                console.log('A code was found, but it was in a invalid format.')
                              }

                        }
                    }
             },
    template: `
            <b-modal id="qr_code_scanner"
                     v-bind:title="qr_title"
                     v-bind:videoSource='videoSource'
                     hide-footer >
                            <div class="alert alert-danger" v-show="qr_error != null">
                                {{qr_error}}
                            </div>
                            <div>
                                   <a href='#' v-for="source in videoSource" v-on:click='selectSource(source.id)' class='btn btn-primary'>@{{source.name}}</a>
                           </div>
                           <div class="large-centered col-lg-12 col-md-12 col-sm-12" style="overflow: hidden;">
                                   <input type="text" ref="qr_result" name='qr_result' v-focus="focused" v-model='qr_result' class="form-control" />
                                   <video id="qrvideo" ref="qrvideo" controls="false" style="display: none;"></video>
                                   <canvas id="qrcanvas" ref='qrcanvas' style="overflow: hidden;" width="400" height="400"></canvas>
                           </div>
                    <div class="modal-footer">
                        <a href='#' v-on:click='dismiss()' class='btn btn-primary'>Cancel</a>
                    </div>
           </b-modal>
            `
    });

I'm expecting it to return a QR Code.

0

There are 0 best solutions below