Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/zxing-cpp/wrappers/wasm/demo_cam_reader.html @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/zxing-cpp/wrappers/wasm/demo_cam_reader.html Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,159 @@ +<!DOCTYPE html> +<html> + +<head> + <title>zxing-cpp/wasm live demo</title> + <link rel="shortcut icon" href="#" /> + <script src="zxing_reader.js"></script> +</head> + +<body style="text-align: center"> + <h2>zxing-cpp/wasm live demo</h2> + <p> + This is a simple demo of the wasm wrapper of <a href="https://github.com/zxing-cpp/zxing-cpp">zxing-cpp</a> + scanning for barcodes in a live video stream. + </p> + + Camera: + <select id="cameraSelector"> + <option value="user">Front Camera</option> + <option value="environment">Back Camera</option> + </select> + + + Format: + <select id="format"> + <option value="" selected="">Any</option> + <option value="Aztec">Aztec</option> + <option value="Code39">Codabar</option> + <option value="CODE_39">Code39</option> + <option value="Code93">Code93</option> + <option value="Code128">Code128</option> + <option value="DataMatrix">DataMatrix</option> + <option value="DataBar">DataBar</option> + <option value="DataBarExpanded">DataBarExpanded</option> + <option value="DataBarLimited">DataBarLimited</option> + <option value="DXFilmEdge">DXFilmEdge</option> + <option value="EAN8">EAN-8</option> + <option value="EAN13">EAN-13</option> + <option value="ITF">ITF</option> + <option value="PDF417">PDF417</option> + <option value="QRCode">QRCode</option> + <option value="MicroQRCode">Micro QRCode</option> + <option value="RMQRCode">rMQR Code</option> + <option value="UPCA">UPC-A</option> + <option value="UPCE">UPC-E</option> + <option value="LinearCodes">Linear Codes</option> + <option value="MatrixCodes">Matrix Codes</option> + </select> + + + Mode: + <select id="mode"> + <option value="true" selected="">Normal</option> + <option value="false">Fast</option> + </select> + <br /><br /> + + <canvas id="canvas" width="640" height="480"></canvas> + <br /><br /> + + <div id="result"></div> + + <script> + var zxing = ZXing().then(function (instance) { + zxing = instance; // this line is supposedly not required but with current emsdk it is :-/ + }); + + const cameraSelector = document.getElementById("cameraSelector"); + const format = document.getElementById("format"); + const mode = document.getElementById("mode"); + const canvas = document.getElementById("canvas"); + const resultElement = document.getElementById("result"); + + const ctx = canvas.getContext("2d", { willReadFrequently: true }); + const video = document.createElement("video"); + video.setAttribute("id", "video"); + video.setAttribute("width", canvas.width); + video.setAttribute("height", canvas.height); + video.setAttribute("autoplay", ""); + + function readBarcodeFromCanvas(canvas, format, mode) { + var imgWidth = canvas.width; + var imgHeight = canvas.height; + var imageData = canvas.getContext('2d').getImageData(0, 0, imgWidth, imgHeight); + var sourceBuffer = imageData.data; + + if (zxing != null) { + var buffer = zxing._malloc(sourceBuffer.byteLength); + zxing.HEAPU8.set(sourceBuffer, buffer); + var result = zxing.readBarcodeFromPixmap(buffer, imgWidth, imgHeight, mode, format); + zxing._free(buffer); + return result; + } else { + return { error: "ZXing not yet initialized" }; + } + } + + function drawResult(code) { + ctx.beginPath(); + ctx.lineWidth = 4; + ctx.strokeStyle = "red"; + // ctx.textAlign = "center"; + // ctx.fillStyle = "#green" + // ctx.font = "25px Arial"; + // ctx.fontWeight = "bold"; + with (code.position) { + ctx.moveTo(topLeft.x, topLeft.y); + ctx.lineTo(topRight.x, topRight.y); + ctx.lineTo(bottomRight.x, bottomRight.y); + ctx.lineTo(bottomLeft.x, bottomLeft.y); + ctx.lineTo(topLeft.x, topLeft.y); + ctx.stroke(); + // ctx.fillText(code.text, (topLeft.x + bottomRight.x) / 2, (topLeft.y + bottomRight.y) / 2); + } + } + + function escapeTags(htmlStr) { + return htmlStr.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); + } + + const processFrame = function () { + ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + + const code = readBarcodeFromCanvas(canvas, format.value, mode.value === 'true'); + if (code.format) { + resultElement.innerText = code.format + ": " + escapeTags(code.text); + drawResult(code) + } else { + resultElement.innerText = "No barcode found"; + } + requestAnimationFrame(processFrame); + }; + + const updateVideoStream = function (deviceId) { + // To ensure the camera switch, it is advisable to free up the media resources + if (video.srcObject) video.srcObject.getTracks().forEach(track => track.stop()); + + navigator.mediaDevices + .getUserMedia({ video: { facingMode: deviceId }, audio: false }) + .then(function (stream) { + video.srcObject = stream; + video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen + video.play(); + processFrame(); + }) + .catch(function (error) { + console.error("Error accessing camera:", error); + }); + }; + + cameraSelector.addEventListener("change", function () { + updateVideoStream(this.value); + }); + + updateVideoStream(); + </script> +</body> + +</html>
