首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Web 掃描二維碼:HTML5 調用攝像頭 + ZXing 解碼完整方案

     編輯:程式設計綜合問答

技術架構

前端 (HTML5/JS)          後端 (Java)
┌─────────────────┐      ┌─────────────────┐
│ getUserMedia()  │      │ ZXing Library   │
│ 獲取視頻流       │ ──▶  │ 解析二維碼       │
│ Canvas 截幂     │      │ 返回業務數據     │
└─────────────────┘      └─────────────────┘

前端實現:HTML5 拍照上傳

<video id="video" width="320" height="240" autoplay playsinline></video>
<canvas id="canvas" width="320" height="240" style="display:none"></canvas>
<button id="scanBtn">掃描二維碼</button>

<script>
const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// 1. 請求攝像頭權限
navigator.mediaDevices.getUserMedia({ 
    video: { facingMode: 'environment' }  // 後置攝像頭
}).then(stream => {
    video.srcObject = stream;
}).catch(err => {
    console.error('攝像頭訪問失敗:', err);
});

// 2. 掃描按鈕點擊
document.getElementById('scanBtn').addEventListener('click', () => {
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    const imageData = canvas.toDataURL('image/png');
    
    // 3. 上傳到後端解析
    fetch('/api/qr/decode', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ image: imageData })
    }).then(res => res.json())
      .then(data => {
          if (data.success) {
              alert('掃描結果: ' + data.content);
              // 觸發業務邏輯
          }
      });
});
</script>

後端實現:ZXing 解碼

@RestController
@RequestMapping("/api/qr")
public class QRController {
    
    @PostMapping("/decode")
    public Result decode(@RequestBody Map payload) {
        String base64Image = payload.get("image");
        // 移除 data:image/png;base64, 前綴
        String base64Data = base64Image.split(",")[1];
        byte[] imageBytes = Base64.getDecoder().decode(base64Data);
        
        try (InputStream is = new ByteArrayInputStream(imageBytes)) {
            BufferedImage image = ImageIO.read(is);
            
            // ZXing 解碼
            BinaryBitmap bitmap = new BinaryBitmap(
                new HybridBinarizer(new BufferedImageLuminanceSource(image))
            );
            Result result = new MultiFormatReader().decode(bitmap);
            
            return Result.success(result.getText());
        } catch (Exception e) {
            return Result.error("二維碼識別失敗: " + e.getMessage());
        }
    }
}

Maven 依賴

<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.5.1</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.5.1</version>
</dependency>

關鍵注意點

  • HTTPS 必須:getUserMedia 需安全上下文 (localhost 除外)
  • 權限處理:用戶拒絕攝像頭權限時的降級方案 (文件上傳)
  • 性能優化:降低視頻分辨率、限制掃描頻率、Worker 線程解碼
  • 兼容性:iOS Safari 需 playsinline、用戶交互後才能啟動攝像頭

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved