HTML5 QR Code Scanner Implementation for Mobile Devices

Mobile QR Code Scanning with HTML5

This implementation enables HTML5 applications to scan QR codes using either the device camera or by selecting images from the photo gallery. The solution is particularly useful for business scenarios where users need to scan document QR codes or manualy enter identification numbers.

HTML Structure

<style>
    .scanner-container {
        width: 100%;
        text-align: center;
        margin: 15px auto;
    }
    
    .video-output {
        width: 320px;
        height: 240px;
        border: 3px solid #333;
        margin: 0 auto;
    }
    
    .scan-result {
        border: 1px solid #ccc;
        padding: 20px;
        width: 70%;
        margin: 10px auto;
    }
    
    .action-button {
        margin: 10px;
        padding: 12px 24px;
        background: #007bff;
        color: white;
        border: none;
        border-radius: 4px;
        cursor: pointer;
    }
    
    .hidden-element {
        display: none;
    }
</style>

<script src="qrcode-decoder.js"></script>
<script src="scanner-controller.js"></script>
        <button class="action-button" onclick="activateCamera()">
            Camera Scan
        </button>
        
        <button class="action-button" onclick="selectFromGallery()">
            Gallery Scan
        </button>
        
        <div class="scan-result" id="decoded-result"></div>
    </div>
</div>

<canvas id="processing-canvas" class="hidden-element"></canvas>

<script>
    initializeScanner();
    activateCamera();
</script>

const galleryHTML = `

const cameraHTML = <video id="camera-stream" autoplay></video>;

function processSelectedImage(files) { if (files.length === 0) return;

const reader = new FileReader();
reader.onload = function(event) {
    canvasContext.clearRect(0, 0, 
        processingCanvas.width, 
        processingCanvas.height);
    QRDecoder.decode(event.target.result);
};
reader.readAsDataURL(files[0]);

}

function setupCanvas(width, height) { processingCanvas = document.getElementById("processing-canvas"); processingCanvas.style.width = width + "px"; processingCanvas.style.height = height + "px"; processingCanvas.width = width; processingCanvas.height = height; canvasContext = processingCanvas.getContext("2d"); canvasContext.clearRect(0, 0, width, height); }

function captureFrame() { if (currentMode !== 1 || !isStreamActive) return;

try {
    canvasContext.drawImage(videoElement, 0, 0);
    QRDecoder.decode();
} catch (error) {
    console.error("Frame processing error:", error);
    setTimeout(captureFrame, 500);
}

}

function handleScanResult(data) { alert("Scanned data: " + data); }

function checkCompatibility() { return !!document.createElement('canvas').getContext && !!window.File && !!window.FileReader; }

function initializeScanner() { if (checkCompatibility()) { setupCanvas(800, 600); QRDecoder.callback = handleScanResult; document.getElementById("scanner-interface").style.display = "block"; activateCamera(); } else { alert("Your browser doesn't support QR scanning. Please try UC Browser."); } }

function activateCamera() { document.getElementById("decoded-result").innerHTML = "Scanning...";

if (currentMode === 1) {
    setTimeout(captureFrame, 500);
    return;
}

const videoContainer = document.getElementById("video-container");
videoContainer.innerHTML = cameraHTML;
videoElement = document.getElementById("camera-stream");

const mediaConstraints = { video: true, audio: false };

if (navigator.mediaDevices?.getUserMedia) {
    navigator.mediaDevices.getUserMedia(mediaConstraints)
        .then(function(stream) {
            videoElement.srcObject = stream;
            videoElement.play();
            isStreamActive = true;
            setTimeout(captureFrame, 500);
        })
        .catch(function(err) {
            console.error("Camera access denied:", err);
            isStreamActive = false;
        });
}

currentMode = 1;

}

function selectFromGallery() { document.getElementById("decoded-result").innerHTML = "";

if (currentMode === 2) return;

const videoContainer = document.getElementById("video-container");
videoContainer.innerHTML = galleryHTML;

const fileInput = document.getElementById("image-selector");
fileInput?.click();

currentMode = 2;

}


</div>### Implementation Notes

- Camera scanning continuously captures and processes video frames
- Gallery scanning processes selected image files
- Automatic back camera preference when available
- Cross-browser media device compatibility handling
- Real-time QR code detection and decoding

The implementation has been tested primarily on Android devices using UC Browser. Additional browser testing may be required for full cross-platform compatibility.

</body></html>

Tags: HTML5 QR Code MediaDevices getUserMedia Canvas API

Posted on Thu, 10 Sep 2026 16:54:19 +0000 by blackandwhite