ericblade / quagga2

An advanced barcode-scanner written in Javascript and TypeScript - Continuation from https://github.com/serratus/quaggajs
MIT License
762 stars 85 forks source link

Having issues with quagga2 barcode reader library #540

Open kemal023 opened 6 months ago

kemal023 commented 6 months ago

I've integrated the Quagga2 barcode scanner (https://github.com/ericblade/quagga2?tab=readme-ov-file#configobject) into my project to scan products and retrieve data from my database. However, I'm encountering a few issues with this library:

Precision Issue: The barcode scanner occasionally detects a different EAN (European Article Number) than the one I scanned. How can I improve the precision of the scanner to ensure accurate detection?

Debug Configuration: I've configured the debug options in Quagga2, but the DrawScanLine feature isn't working as expected. How can I troubleshoot this issue and ensure that the debug features are functioning correctly?

Frequency Adjustment: The default frequency value was set to 10, but I increased it to 1000. However, I'm not sure if this adjustment significantly improves performance in different lighting conditions. What would be an optimal frequency value to enhance scanning performance?

Below is the code snippet I'm using within a popup for the barcode scanner:

<style>
    canvas.drawingBuffer {
        display: none;
    }
</style>
<div>
    <script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.min.js"></script>
    <div id="default-modal" tabindex="-1" aria-hidden="true" class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
        <div class="relative p-4 w-full max-w-2xl max-h-full">
            <!-- Modal content -->
            <div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
                <!-- Modal header -->
                <div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
                    <button type="button" class="text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white" data-modal-hide="default-modal">
                        <svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
                            <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/>
                        </svg>
                        <span class="sr-only">Close modal</span>
                    </button>
                </div>
                <!-- Modal body -->
                <div class="p-4 md:p-5 space-y-4">
                    <div id="camera" type="LiveStream">
                    </div>
                </div>
                <div class="modal-footer" style="display:none"></div>
            </div>
        </div>
    </div>

    <style>
        #camera video{
            width:100%;
            max-width: 640px;

        }

        /*#red-stripe {*/
        /*    position: absolute;*/
        /*    top: 50%;*/
        /*    left: 20px;*/
        /*    width: 600px;*/
        /*    height: 2px;*/
        /*    background: red;*/
        /*}*/
    </style>

    <script>
        const quaggaConf = {
            inputStream: {
                target: document.querySelector("#camera"),
                type: "LiveStream",
                constraints: {
                    width: { min: 640 },
                    height: { min: 480 },
                    facingMode: "environment",
                    aspectRatio: { min: 1, max: 2 }
                }
            },
            debug: {
                drawBoundingBox: false,
                showFrequency: true, // Shows the detected frequency of the barcode
                drawScanline: true, // Draws the red line
                showPattern: false
            },
            frequency: 1000, // Adjust this value to improve performance in different lighting conditions
            locator: {
                halfSample: false,
                patchSize: "small",  // x-small, small, medium, large, x-large
            },
            decoder: {
                readers: ["ean_reader", "ean_2_reader", "ean_8_reader"] // List of active readers, EAN-13 is the default one
            },

        }

        document.getElementById('barcodeScannerBtn').addEventListener('click', function () {
            Quagga.init(quaggaConf, function (err) {
                if (err) {
                    return console.log(err);
                }
                //show camera
                document.getElementById('camera').style.display = 'block';
                Quagga.start();
            });
        });

        Quagga.onDetected(function (result) {
            //fill barcode with the result
            const barcodeInput = document.getElementById('barcode');
            barcodeInput.value = result.codeResult.code;

            // Dispatch an input event
            const event = new Event('input', {
                bubbles: true,
                cancelable: true,
            });
            barcodeInput.dispatchEvent(event);

            //stop the scanner
            Quagga.stop();

            // document.querySelector('[data-modal-hide="default-modal"]').click();

 });
    </script>
</div>

to try this function you can add an button like this in the code:

<button type="button" data-modal-target="default-modal" data-modal-toggle="default-modal" class="mr-4 bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded-full" id="barcodeScannerBtn"><svg class="w-6 h-6 text-gray-800 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
                    <path stroke="white" stroke-linejoin="round" stroke-width="2" d="M4 18V8a1 1 0 0 1 1-1h1.5l1.707-1.707A1 1 0 0 1 8.914 5h6.172a1 1 0 0 1 .707.293L17.5 7H19a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1Z"/>
                    <path stroke="white" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/>
                </svg>
            </button>

Any insights or suggestions on resolving these issues would be greatly appreciated.

github-actions[bot] commented 6 months ago

Thank you for filing an issue! Please be patient. :-)

ericblade commented 6 months ago

There are many different possible ways to filter false readings. A fairly simple way is implemented in my react example:

https://github.com/ericblade/quagga2-react-example/blob/master/src/Scanner.js

That just checks Quagga's internal error count in what it decoded,a nd if the error level is low (under 25%) then accept it.

What I actually use in my existing app, that seems to work rather well (with UPC, ISBN10, ISBN13, though it should apply to EAN also, I'd think):

Validate the barcode with a barcode validation library ( https://github.com/ericblade/barcode-validator ). If the code passes validation, then accept it. Otherwise, if the code doesn't pass validation, but we've read it 5 times with an under 25% error reading, then accept it anyway -- just because it doesn't pass validation, doesn't mean that's not what's actually printed on the barcode.

I get very few misreads with this method, as it's quite difficult to mis-read and still come up with a correct checksum.

I do not have any idea if this method works well with any other type, and I don't validate any other types, but it's probably doable.