欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

条形码区域解码:Web小工具

程序员文章站 2024-03-23 16:54:28
...

条形码解码首先要做定位,找到条形码在图像中的区域。但是有时候受图像质量影响,算法找寻的区域可能产生偏差,最后导致解码失败。这个时候,可以尝试手动选择区域,来辅助条形码的识别。

Web Canvas框选识别条形码

需求:

  1. 在网页中加载条形码图像。
  2. 使用鼠标框选出条形码的区域。
  3. 识别区域中的条形码。

Web Canvas图像显示

创建input选择文件。获取文件对象之后,使用FileReader读取并绘制到canvas上。如果读取的图像太大,可以设定一个最大缩放值:

<input type="file" id="barcode-file" onchange="loadfile()" accept=".jpg,.jpeg,.png,.bmp" />
 
function loadfile() {
            let img = new Image();
            var reader = new FileReader();
            reader.onload = function (evt) {
                img.onload = function () {                    
                    if (img.width > maxLength) {
                        img.height = maxLength * img.height / img.width
                        img.width = maxLength;
                    }
                    else if (img.height > maxLength) {
                        img.width = maxLength * img.width / img.height
                        img.height = maxLength;
                    }
                    canvas.width = img.width;
                    canvas.height = img.height;
                    overlay.width = canvas.width;
                    overlay.height = canvas.height;
                     
                    context.drawImage(img, 0, 0, img.width, img.height);
                };
                img.src = evt.target.result;
            };
            reader.readAsDataURL(name.files[0]);
     
}

鼠标框选矩形区域

要在图像上面绘制出一个矩形框,需要创建另外一个canvas,并把它放置到图像的上面:

<style>
        #container {
          position: relative;
        }
     
        #imageCanvas {
          position: relative;
          z-index: 1;
        }
     
        #overlay {
          position: absolute;
          top: 0;
          left: 0;
          z-index: 2
        }
     
</style>
 
<div id="container">
        <canvas id="imageCanvas"> </canvas>
        <canvas id="overlay"></canvas>
</div>

接下来监听鼠标事件,在鼠标移动的时候绘制矩形:

function clearOverlay() {
            overlayCtx.clearRect(0, 0, overlay.width, overlay.height);
            overlayCtx.strokeStyle = '#ff0000';
            overlayCtx.lineWidth = 5;
}
 
overlay.addEventListener('mousedown', e => {
                    startX = e.offsetX;
                    startY = e.offsetY;
                    isDrawing = true;
                    clearOverlay();
                    overlay.style.cursor = "crosshair";
                });
 
overlay.addEventListener('mousemove', e => {
                    if (isDrawing) {
                        clearOverlay();
                        overlayCtx.beginPath();
                        overlayCtx.rect(startX, startY, e.offsetX - startX, e.offsetY - startY);  
                        overlayCtx.stroke();
                    } 
                    mousePosition.innerHTML = "Cursor: (" + e.offsetX + ", " + e.offsetY + ")";
                });
 
overlay.addEventListener('mouseup', e => {
                    if (isDrawing) {
                        isDrawing = false;
                         
                        mousePosition.innerHTML = "Cursor: (" + e.offsetX + ", " + e.offsetY + ")";
                        region.innerHTML = "Decode a region: (" + startX + ", " + startY + ", " + e.offsetX + ", " + e.offsetY + "). ";
                        overlay.style.cursor = "default";
                    }
 
                });

条形码识别

在鼠标左键抬起的时候,可以获得矩形最终的区域。把这个区域设置到接口中:

overlay.addEventListener('mouseup', e => {
                    if (isDrawing) {
                        isDrawing = false;
                         
                        mousePosition.innerHTML = "Cursor: (" + e.offsetX + ", " + e.offsetY + ")";
                        region.innerHTML = "Decode a region: (" + startX + ", " + startY + ", " + e.offsetX + ", " + e.offsetY + "). ";
                        overlay.style.cursor = "default";
 
                        // Decode a region of the barcode image
                        (async () => {
                            let settings = await barcodereader.getRuntimeSettings();
                            settings.region.regionLeft = startX * 100 / overlay.width;
                            settings.region.regionTop = startY * 100 / overlay.height;
                            settings.region.regionRight = e.offsetX * 100 / overlay.width;
                            settings.region.regionBottom = e.offsetY * 100 / overlay.height;
                            settings.region.regionMeasuredByPercentage = 1;
                            barcodereader.updateRuntimeSettings(settings);
                            try {
                                let decodingStart = Date.now();
                                await barcodereader.decode(name.files[0]).then((results) => {
                                    let decodingEnd = Date.now();
                                    let txts = [];
                                    try {
                                        for (let i = 0; i < results.length; ++i) {
                                            txts.push(results[i].BarcodeText);
                                        }
                                        let barcoderesults = txts.join(', ');
                                    catch (e) {
                                    }
                                });
                            } catch (error) {
                                alert(error);
                            }
                        })();
                    }
 
                });

现在可以很方便的选中一块条形码的区域来查看解码结果。
条形码区域解码:Web小工具

源码

https://gist.github.com/yushulx/b21d0919a1e92e0a320929799a99a5de

相关标签: Barcode JavaScript