25 #include "streamlet-common.h" |
25 #include "streamlet-common.h" |
26 |
26 |
27 /** |
27 /** |
28 * This streamlet extracts QR codes from image files. |
28 * This streamlet extracts QR codes from image files. |
29 * |
29 * |
30 * It provides two attributes: |
30 * It provides three attributes: |
31 * - qr: first QR code found (if any) |
31 * - qr: first QR code found (if any) |
|
32 * - qr_count: number of QR codes found |
32 * - qr_xml: XML containing all QR cpdes found an additional metadata |
33 * - qr_xml: XML containing all QR cpdes found an additional metadata |
33 * |
34 * |
34 */ |
35 */ |
35 class QRStreamlet : public Streamlet { |
36 class QRStreamlet : public Streamlet { |
36 private: |
37 private: |
37 |
38 |
38 const wstring XMLNS = L"tag:globalcode.info,2018:qr:FIXME:final-xmlns"; // FIXME: correct xmlns URI |
39 const wstring XMLNS = L"tag:globalcode.info,2018:qr:FIXME:final-xmlns"; // FIXME: correct xmlns URI |
|
40 |
|
41 class Point { |
|
42 public: |
|
43 int x; |
|
44 int y; |
|
45 }; |
39 |
46 |
40 class Symbol { |
47 class Symbol { |
41 public: |
48 public: |
42 int id; |
49 int id; |
43 std::wstring value; |
50 std::wstring value; |
44 std::wstring type; |
51 std::wstring type; |
45 int x; |
52 int x; |
46 int y; |
53 int y; |
47 int width; |
54 int width; |
48 int height; |
55 int height; |
|
56 std::vector<Point> polygon; |
49 }; |
57 }; |
50 |
58 |
51 std::vector<Symbol> findSymbols(std::wstring fileName) { |
59 std::vector<Symbol> findSymbols(std::wstring fileName) { |
52 std::vector<Symbol> result; |
60 std::vector<Symbol> result; |
53 |
61 |
84 int y = symbol->get_location_y(i); |
92 int y = symbol->get_location_y(i); |
85 minX = minX ? std::min(minX, x) : x; |
93 minX = minX ? std::min(minX, x) : x; |
86 minY = minY ? std::min(minY, y) : y; |
94 minY = minY ? std::min(minY, y) : y; |
87 maxX = std::max(maxX, x); |
95 maxX = std::max(maxX, x); |
88 maxY = std::max(maxY, y); |
96 maxY = std::max(maxY, y); |
|
97 s.polygon.push_back({x, y}); |
89 } |
98 } |
90 |
99 |
91 s.x = minX; |
100 s.x = minX; |
92 s.y = minY; |
101 s.y = minY; |
93 s.width = maxX - minX; |
102 s.width = maxX - minX; |
145 // xmlWriter.writeEndElement(); |
154 // xmlWriter.writeEndElement(); |
146 |
155 |
147 for (Symbol s : symbols) { |
156 for (Symbol s : symbols) { |
148 xmlWriter.writeStartElement(L"symbol"); |
157 xmlWriter.writeStartElement(L"symbol"); |
149 xmlWriter.writeTextElement(L"value",{}, s.value); |
158 xmlWriter.writeTextElement(L"value",{}, s.value); |
|
159 |
|
160 // TODO: well-designed XML schema |
|
161 // TODO: synchronize/share common XML parts with relpipe-in-qr |
|
162 xmlWriter.writeStartElement(L"rectangular-box"); |
150 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
163 xmlWriter.writeTextElement(L"x",{}, std::to_wstring(s.x)); |
151 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |
164 xmlWriter.writeTextElement(L"y",{}, std::to_wstring(s.y)); |
152 xmlWriter.writeTextElement(L"height",{}, std::to_wstring(s.height)); |
165 xmlWriter.writeTextElement(L"height",{}, std::to_wstring(s.height)); |
153 xmlWriter.writeTextElement(L"width",{}, std::to_wstring(s.width)); |
166 xmlWriter.writeTextElement(L"width",{}, std::to_wstring(s.width)); |
154 // TODO: polygon |
167 xmlWriter.writeEndElement(); |
|
168 |
|
169 xmlWriter.writeStartElement(L"polygon"); |
|
170 for (Point p : s.polygon) xmlWriter.writeEmptyElement(L"point",{L"x", std::to_wstring(p.x), L"y", std::to_wstring(p.y)}); |
|
171 xmlWriter.writeEndElement(); |
|
172 |
155 xmlWriter.writeEndElement(); |
173 xmlWriter.writeEndElement(); |
156 } |
174 } |
157 |
175 |
158 xmlWriter.writeEndElement(); |
176 xmlWriter.writeEndElement(); |
159 |
177 |