iT邦幫忙

0

手機版網頁Qrcode掃描失敗:邊寬小於一公分,黑底白色(反白)。

  • 分享至 

  • xImage

客戶有一個需求是想要用手機掃描Qrcode
但是他們給過來的code是黑底白色的且寬度小於一公分

目前是使用了html5-qrcode的技術
調便了各種參數還是無法使用...

也問過ChatGPT
給出的建議都也試遍了還是無法 QQ

想問各位大前輩
有沒有人解決過這樣的需求?
請指點小的一點方向~~~TAT

目前我的code:
HTML--->

<script src="https://reeteshghimire.com.np/wp-content/uploads/2021/05/html5-qrcode.min_.js"></script>

<div class="row">
  <div class="col">
    <div style="width:300px;" id="reader"></div>
  </div>
  <div class="col" style="padding:30px;">
    <h4>SCAN RESULT</h4>
    <div id="result">Result Here</div>
  </div>
</div>

CSS--->

  .result{
    background-color: green;
    color:#fff;
    padding:20px;
  }
  .row{
    display:flex;
  }

JS--->

function onScanSuccess(qrCodeMessage) {
    document.getElementById('result').innerHTML = '<span class="result">'+qrCodeMessage+'</span>';
}
  
function onScanError(errorMessage) {
  //handle scan error
}


var html5QrcodeScanner = new Html5QrcodeScanner(
    "reader", { 
      fps: 10,//讀取速度  
      qrbox: 50,//qrcode掃瞄區大小
      resolution: 1024,//解析度
      scale: 5.0,//啟用等比縮放
      area: 0.3,//擴展QR code的區域
      findLight: true,//尋找光點
      colorInvert: true,//色彩反轉
      angle: -90,//設置掃描視角
      minimumBlur: 0.01,//最小模糊程度
      readers: ["code_128_reader", "ean_reader"],//解碼器
      aspectRatio: 1,//設定鏡頭的寬高比
      cameraIdOrConfig: { 
        facingMode: "environment", 
        zoom: 3.0 
      }//設定鏡頭的縮放比例
    }
);

  
html5QrcodeScanner.render(onScanSuccess, onScanError);
看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2023-03-21 16:22:42 檢舉
跟你客戶反應看能不能大點啊,這影響有可能是硬體限制而非完全的軟體限制。
pppppeter iT邦新手 5 級 ‧ 2023-03-21 17:26:01 檢舉
他們好像類似引導要用的,平面已經印下去了,只能軟體跟上了 QQ ...
淺水員 iT邦大師 6 級 ‧ 2023-03-21 19:02:50 檢舉
我以前用過另外一個套件(https://github.com/cozmo/jsQR)
可以試試看會不會比較好掃

更正:目前問題似乎是無法掃反白,包含我說的這個也是
細節寫在下面的回答
QQ iT邦新手 5 級 ‧ 2023-03-27 10:46:55 檢舉
zxing-cpp 的 Wasm 版可以考慮
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
淺水員
iT邦大師 6 級 ‧ 2023-03-22 01:08:18
最佳解答

我測試了一下,包含:

  1. 發問者給的程式碼
  2. https://github.com/cozmo/jsQR 裡面的 demo
  3. https://github.com/mebjas/html5-qrcode 裡面的 demo

都無法掃描出反白的 QR Code
我想這一步要先解決,才要擔心圖片太小的問題

做了一個測試用的QR Code 頁面
螢幕上左右各有正常與反白的 QR Code 可以測試

PS. 我直接用 firefox 內建的掃描是可以掃出反白的 QR Code 的


2023-03-29 更新

後來發現 https://github.com/nimiq/qr-scanner 有支援反白
使用上也滿方便的,是我目前最佳的解法

看更多先前的回應...收起先前的回應...
pppppeter iT邦新手 5 級 ‧ 2023-03-22 13:38:12 檢舉

但理想可能還是要以Chrome瀏覽器為主 TAT
那我往掃描"反白"的問題下去試著解決看看~

謝謝前輩 :D

淺水員 iT邦大師 6 級 ‧ 2023-03-22 14:14:31 檢舉

html5-qrocde 的 issue#94 有人提到 https://github.com/cozmo/jsQR 可以掃反白

jsQR 的說明也有寫到預設是開啟的,只是它 Demo 把這功能關閉了
(我猜是效能的關係)

下面程式碼我測試過,可以掃出反白

<!DOCTYPE html>
<html lang="zh-Hant-TW">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>鏡頭測試</title>
    
    <!-- npm install jsqr -->
    <script src="./node_modules/jsqr/dist/jsQR.js"></script>
    
</head>
<body>
    <button id="start">開始</button>
    <button id="stop">停止</button>
    <p></p>
    <hr>
    <canvas></canvas>
    <script type="module">
        import Camera from './camera.js';

        // 相機
        const cam = new Camera(document.querySelector('canvas'));
        
        // 顯示掃出來的結果
        const logP = document.querySelector('p');

        // 開始按鈕
        document.querySelector('#start').addEventListener('click', ()=>{
            cam.start();
            cam.onNextFrame = readQrCode;
            logP.textContent = '掃描結果: 無';
        });

        // 停止按鈕
        document.querySelector('#stop').addEventListener('click', ()=>{
            cam.stop();
        });

        function readQrCode(data) {
            const code = jsQR(data.data, data.width, data.height);
            if(code) {
                logP.textContent = `掃描結果: ${code.data}`;
            }
            cam.onNextFrame = readQrCode;
        }
    </script>
</body>
</html>

camera.js
(稍微包裝一下鏡頭的處理)

export default class Camera {
    /**
     * constructor
     * @param {canvasElement} canvasElement 鏡頭開啟時,會繪製在這邊
     */
    constructor(canvasElement) {
        this.canvas = canvasElement;
        this.video = document.createElement("video");
        this.video.srcObject = null;
        this.resizeFlag = false;

        /** 
         * @var {callback} 透過設定 onNextFrame 可以捕捉到下一個畫面
         *                 捕捉到後呼叫此函數,並且 onNextFrame 會被設定為 null
         */
        this.onNextFrame = null;        
    }

    /**
     * 開啟鏡頭(瀏覽器會跳出要求權限)
     * (開啟後可以透過設定 onNextFrame 捕捉畫面)
     */
    start() {
        // 已經啟動
        if (this.video.srcObject) {
            return;
        }
        // Use facingMode: environment to attemt to get the front camera on phones
        navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then((stream) => {
            this.video.srcObject = stream;
            this.video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
            this.video.play();
            this.resizeFlag = true;
            requestAnimationFrame(this._tick.bind(this));
        });
    }

    /**
     * 停止使用鏡頭
     */
    stop() {
        if (this.video.srcObject) {
            const tracks = this.video.srcObject.getTracks();
            tracks.forEach(function (track) {
                track.stop();
            });
            this.video.srcObject = null;
        }
    }

    _tick() {
        const video = this.video;
        if (video.readyState === video.HAVE_ENOUGH_DATA) {
            const canvas = this.canvas;
            const ctx = canvas.getContext('2d');
            if (this.resizeFlag) {
                canvas.height = video.videoHeight;
                canvas.width = video.videoWidth;
                this.resizeFlag = false;
            }
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
            if (this.onNextFrame) {
                let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                let callback = this.onNextFrame;
                this.onNextFrame = null;
                callback(imageData);
            }
        }
        requestAnimationFrame(this._tick.bind(this));
    }
}

效能部分你可以再調整看看
例如 jsQR 可以移到 web worker 去跑

淺水員 iT邦大師 6 級 ‧ 2023-03-27 16:49:21 檢舉

我後來發現另外一個更好用的
https://github.com/nimiq/qr-scanner

  1. 支援反白
  2. 鏡頭部分也幫我們處理好了,不用自己處理
  3. 有考慮效能問題,預設就是跑 worker,還能設定每秒最多處理幾個畫面
pppppeter iT邦新手 5 級 ‧ 2023-03-29 15:05:50 檢舉

qr-scanner 可以~~~(灑花)
謝謝前輩 :D

0
揮揮手
iT邦研究生 5 級 ‧ 2023-03-21 17:03:35

硬體限制 也有影響
建議直接請對方出通用圖
有時手機鏡頭 有縮放限制
圖片太小 被模糊化
就更本掃不到東西

這邊引用 quickmark視力圖

前五個 我手機就掃不到了

pppppeter iT邦新手 5 級 ‧ 2023-03-21 17:25:07 檢舉

他是第三個,我哭 TAT ...

淺水員 iT邦大師 6 級 ‧ 2023-03-21 17:45:31 檢舉

我的千元手機剛好能掃到第 3 個
不過是掃螢幕上的(拿 A4 紙比對縮放)

後來發現印出來更好掃,全部都掃得到

我要發表回答

立即登入回答