-
Notifications
You must be signed in to change notification settings - Fork 0
/
demo_cam_reader.html
154 lines (134 loc) · 4.69 KB
/
demo_cam_reader.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!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="front">Front Camera</option>
<option value="back">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="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) {
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>