| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- <!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>
|