-
Notifications
You must be signed in to change notification settings - Fork 53
/
main.js
121 lines (100 loc) · 3.6 KB
/
main.js
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
function generateMarkerSvg(width, height, bits, fixPdfArtifacts = true) {
var svg = document.createElement('svg');
svg.setAttribute('viewBox', '0 0 ' + (width + 2) + ' ' + (height + 2));
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('shape-rendering', 'crispEdges');
// Background rect
var rect = document.createElement('rect');
rect.setAttribute('x', 0);
rect.setAttribute('y', 0);
rect.setAttribute('width', width + 2);
rect.setAttribute('height', height + 2);
rect.setAttribute('fill', 'black');
svg.appendChild(rect);
// "Pixels"
for (var i = 0; i < height; i++) {
for (var j = 0; j < width; j++) {
var white = bits[i * height + j];
if (!white) continue;
var pixel = document.createElement('rect');;
pixel.setAttribute('width', 1);
pixel.setAttribute('height', 1);
pixel.setAttribute('x', j + 1);
pixel.setAttribute('y', i + 1);
pixel.setAttribute('fill', 'white');
svg.appendChild(pixel);
if (!fixPdfArtifacts) continue;
if ((j < width - 1) && (bits[i * height + j + 1])) {
pixel.setAttribute('width', 1.5);
}
if ((i < height - 1) && (bits[(i + 1) * height + j])) {
var pixel2 = document.createElement('rect');;
pixel2.setAttribute('width', 1);
pixel2.setAttribute('height', 1.5);
pixel2.setAttribute('x', j + 1);
pixel2.setAttribute('y', i + 1);
pixel2.setAttribute('fill', 'white');
svg.appendChild(pixel2);
}
}
}
return svg;
}
var dict;
function generateArucoMarker(width, height, dictName, id) {
console.log('Generate ArUco marker ' + dictName + ' ' + id);
var bytes = dict[dictName][id];
var bits = [];
var bitsCount = width * height;
// Parse marker's bytes
for (var byte of bytes) {
var start = bitsCount - bits.length;
for (var i = Math.min(7, start - 1); i >= 0; i--) {
bits.push((byte >> i) & 1);
}
}
return generateMarkerSvg(width, height, bits);
}
// Fetch markers dict
var loadDict = fetch('dict.json').then(function(res) {
return res.json();
}).then(function(json) {
dict = json;
});
function init() {
var dictSelect = document.querySelector('.setup select[name=dict]');
var markerIdInput = document.querySelector('.setup input[name=id]');
var sizeInput = document.querySelector('.setup input[name=size]');
var saveButton = document.querySelector('.save-button');
function updateMarker() {
var markerId = Number(markerIdInput.value);
var size = Number(sizeInput.value);
var option = dictSelect.options[dictSelect.selectedIndex];
var dictName = option.value;
var width = Number(option.getAttribute('data-width'));
var height = Number(option.getAttribute('data-height'));
var maxId = (Number(option.getAttribute('data-number')) || 1000) - 1;
markerIdInput.setAttribute('max', maxId);
if (markerId > maxId) {
markerIdInput.value = maxId;
markerId = maxId;
}
// Wait until dict data is loaded
loadDict.then(function() {
// Generate marker
var svg = generateArucoMarker(width, height, dictName, markerId, size);
svg.setAttribute('width', size + 'mm');
svg.setAttribute('height', size + 'mm');
document.querySelector('.marker').innerHTML = svg.outerHTML;
saveButton.setAttribute('href', 'data:image/svg;base64,' + btoa(svg.outerHTML.replace('viewbox', 'viewBox')));
saveButton.setAttribute('download', dictName + '-' + markerId + '.svg');
document.querySelector('.marker-id').innerHTML = 'ID ' + markerId;
})
}
updateMarker();
dictSelect.addEventListener('change', updateMarker);
dictSelect.addEventListener('input', updateMarker);
markerIdInput.addEventListener('input', updateMarker);
sizeInput.addEventListener('input', updateMarker);
}
init();