QRtsy 0.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qrtsy-0.15.0/LICENSE +21 -0
- qrtsy-0.15.0/PKG-INFO +375 -0
- qrtsy-0.15.0/README.md +347 -0
- qrtsy-0.15.0/pyproject.toml +103 -0
- qrtsy-0.15.0/src/qrtsy/__init__.py +54 -0
- qrtsy-0.15.0/src/qrtsy/background.py +45 -0
- qrtsy-0.15.0/src/qrtsy/cli.py +169 -0
- qrtsy-0.15.0/src/qrtsy/color.py +118 -0
- qrtsy-0.15.0/src/qrtsy/compensate.py +89 -0
- qrtsy-0.15.0/src/qrtsy/dither.py +82 -0
- qrtsy-0.15.0/src/qrtsy/exceptions.py +2 -0
- qrtsy-0.15.0/src/qrtsy/integrations/__init__.py +0 -0
- qrtsy-0.15.0/src/qrtsy/integrations/segno.py +76 -0
- qrtsy-0.15.0/src/qrtsy/integrations/segno_adapter.py +102 -0
- qrtsy-0.15.0/src/qrtsy/integrations/segno_plugin.py +69 -0
- qrtsy-0.15.0/src/qrtsy/model.py +74 -0
- qrtsy-0.15.0/src/qrtsy/options.py +105 -0
- qrtsy-0.15.0/src/qrtsy/pixels.py +47 -0
- qrtsy-0.15.0/src/qrtsy/presets.py +258 -0
- qrtsy-0.15.0/src/qrtsy/py.typed +0 -0
- qrtsy-0.15.0/src/qrtsy/render.py +299 -0
- qrtsy-0.15.0/src/qrtsy/server.py +466 -0
- qrtsy-0.15.0/src/qrtsy/server_app.py +226 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/app.css +248 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/app.js +565 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/docs.css +284 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/index.html +271 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/logo.js +215 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/qrtsy-ico.svg +1 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/qrtsy-icon.png +0 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/what.html +648 -0
- qrtsy-0.15.0/src/qrtsy/server_assets/what.template.html +43 -0
- qrtsy-0.15.0/src/qrtsy/texture.py +632 -0
qrtsy-0.15.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 by Ricardo Newbery
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
qrtsy-0.15.0/PKG-INFO
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: QRtsy
|
|
3
|
+
Version: 0.15.0
|
|
4
|
+
Summary: Encoder-neutral artistic QR rendering with adaptive image texture, semantic function patterns, presets, and QR-aware compensation
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: Ricardo Newbery
|
|
8
|
+
Author-email: ric@digitalmarbles.com
|
|
9
|
+
Requires-Python: >=3.11, <4.0
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Provides-Extra: segno
|
|
21
|
+
Provides-Extra: server
|
|
22
|
+
Requires-Dist: litestar[standard] (>=2.24,<3) ; extra == "server"
|
|
23
|
+
Requires-Dist: pillow (>=12.3.0,<13.0.0)
|
|
24
|
+
Requires-Dist: segno (>=1.6.6,<2) ; extra == "segno"
|
|
25
|
+
Requires-Dist: segno (>=1.6.6,<2) ; extra == "server"
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# The QRtsy Project
|
|
30
|
+
|
|
31
|
+
<img align="left" width="110" height="110"
|
|
32
|
+
src="https://codeberg.org/newbery/qrtsy/raw/branch/master/src/qrtsy/server_assets/qrtsy-icon.png">
|
|
33
|
+
|
|
34
|
+
**QRtsy** (pronounced **“cue-artsy”**) is an experimental Python toolkit for
|
|
35
|
+
making pretty QR codes.
|
|
36
|
+
|
|
37
|
+
**QRtsy** combines a normal QR matrix with a source image, preserves the pixels that a
|
|
38
|
+
scanner most needs to sample, and leaves the remaining pixels available for the
|
|
39
|
+
image and optional texture effects. The result is a playground for exploring the
|
|
40
|
+
tradeoff between **visual appearance** and **scan reliability**.
|
|
41
|
+
|
|
42
|
+
**QRtsy** is designed primarily as a reusable, encoder-neutral Python library. It
|
|
43
|
+
also includes an optional [Segno](https://segno.readthedocs.io/) integration, a
|
|
44
|
+
command-line interface, and a local browser application for interactively trying
|
|
45
|
+
different settings.
|
|
46
|
+
|
|
47
|
+
> **QRtsy is alpha software.** Artistic QR codes deliberately spend some of the
|
|
48
|
+
> robustness of a conventional QR symbol. Always test generated codes with the
|
|
49
|
+
> actual phones, cameras, print sizes, display sizes, distances, angles, and
|
|
50
|
+
> lighting conditions in which you expect them to be used.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## Installation
|
|
54
|
+
|
|
55
|
+
QRtsy requires **Python 3.11 or newer**.
|
|
56
|
+
|
|
57
|
+
It is a good idea to install QRtsy into a dedicated Python virtual environment
|
|
58
|
+
rather than into your system Python. From the directory where you want to work:
|
|
59
|
+
|
|
60
|
+
```console
|
|
61
|
+
python -m venv .venv
|
|
62
|
+
source .venv/bin/activate
|
|
63
|
+
python -m pip install --upgrade pip
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The rest of the installation instructions below use the standard Python `pip`
|
|
67
|
+
command installed within this **activated** virtual environment. If it's not
|
|
68
|
+
activated, you'll probably install the library somewhere unexpected and that
|
|
69
|
+
will just be confusing and maybe even break things. Remember to **activate**.
|
|
70
|
+
|
|
71
|
+
> Instead of using `pip` directly, most Python code jockeys these days instead
|
|
72
|
+
> tend to use various third-party project tools to manage project virtual
|
|
73
|
+
> environments like [Poetry](https://python-poetry.org/) or
|
|
74
|
+
> [UV](https://docs.astral.sh/uv/). Pick your favorite tooling.
|
|
75
|
+
|
|
76
|
+
To install just the core QRtsy library with the encoder-neutral Pillow renderer:
|
|
77
|
+
|
|
78
|
+
```console
|
|
79
|
+
pip install qrtsy
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
To install QRtsy with Segno support for the convenience API, command-line
|
|
83
|
+
interface, and Segno converter plugin:
|
|
84
|
+
|
|
85
|
+
```console
|
|
86
|
+
pip install 'qrtsy[segno]'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Or to install QRtsy with the local browser application, which also includes Segno:
|
|
90
|
+
|
|
91
|
+
```console
|
|
92
|
+
pip install 'qrtsy[server]'
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Quickstart: Browser UI
|
|
96
|
+
|
|
97
|
+
After QRtsy has been installed, the easiest way to explore its features is with
|
|
98
|
+
the local web application:
|
|
99
|
+
|
|
100
|
+
```console
|
|
101
|
+
qrtsy-server
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Then open `http://127.0.0.1:8000/` in your web browser.
|
|
105
|
+
|
|
106
|
+
Upload an image, enter the text or URL to encode, and experiment with the
|
|
107
|
+
controls while QRtsy updates the preview.
|
|
108
|
+
|
|
109
|
+
The UI includes full-color, posterized, and monochrome image modes; QR version,
|
|
110
|
+
mask, and error-correction controls; sampling-core sizing; function-pattern
|
|
111
|
+
shrinking; several free-pixel texture algorithms; optional luminance
|
|
112
|
+
compensation; built-in and custom presets; per-setting undo; and PNG download.
|
|
113
|
+
|
|
114
|
+
The **How does this work?** link opens the built-in manual at `/what`. The source
|
|
115
|
+
for that guide is also readable directly in the repository at
|
|
116
|
+
[`docs/what.md`](docs/what.md).
|
|
117
|
+
|
|
118
|
+
The server binds to `127.0.0.1` by default. Uploaded and generated images are
|
|
119
|
+
processed in memory rather than written to the server filesystem.
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
## Quickstart: Python
|
|
123
|
+
|
|
124
|
+
For most applications, the Segno convenience API is the simplest place to
|
|
125
|
+
start:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
from qrtsy import RenderOptions
|
|
129
|
+
from qrtsy.integrations.segno import save
|
|
130
|
+
|
|
131
|
+
save(
|
|
132
|
+
"https://example.com/",
|
|
133
|
+
"portrait.jpg",
|
|
134
|
+
"qrcode.png",
|
|
135
|
+
RenderOptions(
|
|
136
|
+
module_size=8,
|
|
137
|
+
core_size=3,
|
|
138
|
+
border=4,
|
|
139
|
+
),
|
|
140
|
+
segno_options={"error": "H", "version": 6},
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Segno is optional because QRtsy itself does not encode payloads. The core
|
|
145
|
+
renderer consumes an encoder-neutral semantic `ModuleMatrix`, so other QR
|
|
146
|
+
encoders can be adapted without coupling the renderer to Segno.
|
|
147
|
+
|
|
148
|
+
If you already have a Segno QR code, QRtsy can render that directly:
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
import segno
|
|
152
|
+
|
|
153
|
+
from qrtsy import RenderOptions
|
|
154
|
+
from qrtsy.integrations.segno import save_qr
|
|
155
|
+
|
|
156
|
+
qr = segno.make_qr("https://example.com/", error="H")
|
|
157
|
+
save_qr(
|
|
158
|
+
qr,
|
|
159
|
+
"portrait.jpg",
|
|
160
|
+
"qrcode.png",
|
|
161
|
+
RenderOptions(module_size=8, core_size=3, border=4),
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
When QRtsy and Segno are installed together, QRtsy also registers a Segno
|
|
166
|
+
converter named `qrtsy`:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
qr.to_qrtsy(
|
|
170
|
+
"qrcode.png",
|
|
171
|
+
image="portrait.jpg",
|
|
172
|
+
module_size=8,
|
|
173
|
+
core_size=3,
|
|
174
|
+
border=4,
|
|
175
|
+
)
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
For a direct example of the encoder-neutral `ModuleMatrix` API, see
|
|
179
|
+
[`examples/matrix.py`](examples/matrix.py).
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
## Quickstart: Command line
|
|
183
|
+
|
|
184
|
+
The `qrtsy` command uses the optional Segno integration:
|
|
185
|
+
|
|
186
|
+
```console
|
|
187
|
+
qrtsy \
|
|
188
|
+
'https://example.com/' \
|
|
189
|
+
portrait.jpg \
|
|
190
|
+
qrcode.png \
|
|
191
|
+
--error H \
|
|
192
|
+
--version 6 \
|
|
193
|
+
--module-size 8 \
|
|
194
|
+
--core-size 3 \
|
|
195
|
+
--border 4
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The CLI defaults to QR version 6. Use `--version auto` to let Segno choose the
|
|
199
|
+
smallest version that fits the payload.
|
|
200
|
+
|
|
201
|
+
For all available options:
|
|
202
|
+
|
|
203
|
+
```console
|
|
204
|
+
qrtsy --help
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Highlights
|
|
208
|
+
|
|
209
|
+
QRtsy currently supports:
|
|
210
|
+
|
|
211
|
+
- full-color, posterized, and monochrome image backgrounds;
|
|
212
|
+
- cover, contain, and stretch image fitting;
|
|
213
|
+
- configurable module size, quiet zone, and central QR sampling-core size;
|
|
214
|
+
- semantic treatment of data and QR function-pattern modules;
|
|
215
|
+
- optional shrinking of finder/separator, alignment, and timing patterns to
|
|
216
|
+
expose more of the image;
|
|
217
|
+
- constrained Floyd–Steinberg dithering for monochrome rendering;
|
|
218
|
+
- optional free-pixel texture using ordered dither, seeded noise, randomized
|
|
219
|
+
error diffusion, or directional flow diffusion;
|
|
220
|
+
- adaptive texture fade to keep texture concentrated in visually suitable image
|
|
221
|
+
regions;
|
|
222
|
+
- QR-aware local luminance compensation;
|
|
223
|
+
- built-in presets plus custom Python and browser presets;
|
|
224
|
+
- JSON preset import/export;
|
|
225
|
+
- an optional Segno adapter and Segno converter plugin;
|
|
226
|
+
- a CLI and a Litestar/Uvicorn local experimentation server.
|
|
227
|
+
|
|
228
|
+
Most of these controls exist because there is no single “best” artistic QR code.
|
|
229
|
+
A setting that looks great for one photograph, payload, output size, and scanner
|
|
230
|
+
may perform badly for another.
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
## How it works
|
|
234
|
+
|
|
235
|
+
QRtsy separates **QR encoding** from **QR rendering**.
|
|
236
|
+
|
|
237
|
+
An encoder adapter converts a QR symbol into a semantic matrix whose modules are
|
|
238
|
+
classified as data, finder, separator, timing, alignment, format, version, fixed
|
|
239
|
+
dark, and so on. This is more information than a simple dark/light matrix and
|
|
240
|
+
lets the renderer treat different parts of the QR symbol differently.
|
|
241
|
+
|
|
242
|
+
For image-bearing modules, QRtsy can replace only a centered **sampling core**
|
|
243
|
+
with the required black or white QR value instead of painting the entire module.
|
|
244
|
+
The surrounding pixels remain available to show the source image. QR function
|
|
245
|
+
patterns can remain fully rendered, or selected patterns can be shrunk
|
|
246
|
+
explicitly for more aggressive experiments.
|
|
247
|
+
|
|
248
|
+
Optional texture passes can make the regular sampling-core grid less visually
|
|
249
|
+
obvious. Optional local compensation can then nudge free pixels within each
|
|
250
|
+
module to recover some of the luminance changed by forced QR pixels and texture.
|
|
251
|
+
|
|
252
|
+
For a walkthrough of the rendering pipeline, every UI setting, QR anatomy,
|
|
253
|
+
texture modes, compensation, and scannability tradeoffs, see
|
|
254
|
+
[`docs/what.md`](docs/what.md).
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
## Presets
|
|
258
|
+
|
|
259
|
+
QRtsy currently ships with three built-in renderer presets:
|
|
260
|
+
|
|
261
|
+
- `default` — the normal `RenderOptions` defaults;
|
|
262
|
+
- `scan-priority` — a more conservative starting point with a four-module quiet
|
|
263
|
+
zone, large sampling cores, protected timing patterns, and no optional texture
|
|
264
|
+
or compensation;
|
|
265
|
+
- `small-core-textured` — a more aggressive experimental style using one-pixel
|
|
266
|
+
cores and randomized error-diffusion texture.
|
|
267
|
+
|
|
268
|
+
For example:
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from qrtsy import get_preset
|
|
272
|
+
from qrtsy.integrations.segno import save
|
|
273
|
+
|
|
274
|
+
options = get_preset("scan-priority").options
|
|
275
|
+
save("https://example.com/", "portrait.jpg", "qrcode.png", options)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Custom Python presets are process-local. Custom presets created in the browser
|
|
279
|
+
UI are stored in that browser's local storage and can be exported to or imported
|
|
280
|
+
from JSON.
|
|
281
|
+
|
|
282
|
+
## Scannability
|
|
283
|
+
|
|
284
|
+
QR error correction helps recover damaged codewords, but it does not make
|
|
285
|
+
arbitrary artistic changes safe. QRtsy intentionally exposes controls that can
|
|
286
|
+
make a symbol less robust.
|
|
287
|
+
|
|
288
|
+
A few practical rules of thumb:
|
|
289
|
+
|
|
290
|
+
- larger sampling cores are generally more scannable than smaller ones;
|
|
291
|
+
- leaving finder, alignment, and timing structures intact is generally more
|
|
292
|
+
scannable than shrinking them;
|
|
293
|
+
- try at least a four-module quiet zone since that is the QR standard;
|
|
294
|
+
- texture and compensation are aesthetic tools; they can't increase scanning robustness;
|
|
295
|
+
- test the final physical or displayed result, not just a large desktop preview.
|
|
296
|
+
|
|
297
|
+
The built-in `scan-priority` preset is a useful conservative starting point, but
|
|
298
|
+
it is still not a guarantee. See the [scannability discussion](docs/what.md#scannability)
|
|
299
|
+
for more detail.
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
## Development
|
|
303
|
+
|
|
304
|
+
The project uses Poetry and Poe the Poet:
|
|
305
|
+
|
|
306
|
+
```console
|
|
307
|
+
poetry install --all-extras
|
|
308
|
+
poetry run poe check
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Useful development tasks include:
|
|
312
|
+
|
|
313
|
+
```console
|
|
314
|
+
poetry run poe lint
|
|
315
|
+
poetry run poe format
|
|
316
|
+
poetry run poe typecheck
|
|
317
|
+
poetry run poe test
|
|
318
|
+
poetry run poe coverage
|
|
319
|
+
poetry run poe docs
|
|
320
|
+
poetry run poe build
|
|
321
|
+
poetry run poe server
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
`poe check` runs project validation, linting, format checking, type checking,
|
|
325
|
+
tests, and a documentation-generation consistency check.
|
|
326
|
+
|
|
327
|
+
The server manual is generated from `docs/what.md` by `docs/build_docs.py`.
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Current limitations
|
|
331
|
+
|
|
332
|
+
QRtsy is still deliberately experimental. Among the current limitations:
|
|
333
|
+
|
|
334
|
+
- output is raster/Pillow only;
|
|
335
|
+
- the QRtsy-supplied Segno adapter does not support Micro QR;
|
|
336
|
+
- local compensation can be slow;
|
|
337
|
+
- the renderer does not calculate or enforce a Reed–Solomon damage budget;
|
|
338
|
+
- Python custom presets are process-local while browser presets are local to
|
|
339
|
+
that browser;
|
|
340
|
+
- Segno-specific module classification remains isolated behind the adapter
|
|
341
|
+
because Segno documents that interface as experimental.
|
|
342
|
+
|
|
343
|
+
Expect APIs and rendering behavior to change while the project is in alpha.
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
## Acknowledgements
|
|
347
|
+
|
|
348
|
+
QRtsy owes its biggest debt to Andrew Taylor's
|
|
349
|
+
[Dithered QR Code Generator](https://www.andrewt.net/dithered-qr-codes/) and his
|
|
350
|
+
excellent explanation of
|
|
351
|
+
[how the technique works](https://www.andrewt.net/dithered-qr-codes/wtf/).
|
|
352
|
+
His use of small forced QR samples and error diffusion was the starting point for
|
|
353
|
+
much of this experimentation.
|
|
354
|
+
|
|
355
|
+
QRtsy does not try to reinvent QR encoding itself. The first supplied integration
|
|
356
|
+
uses [Segno](https://segno.readthedocs.io/), whose encoder, semantic module output,
|
|
357
|
+
and plugin architecture make it a particularly useful match for the project.
|
|
358
|
+
|
|
359
|
+
The built-in manual contains additional links to QR standards, tutorials,
|
|
360
|
+
research papers, and other aesthetic QR-code projects.
|
|
361
|
+
|
|
362
|
+
The QRtsy project icon was generated by the QRtsy server app using
|
|
363
|
+
*Painter Artist* by Gan Khoon Lay from
|
|
364
|
+
[Noun Project](https://thenounproject.com/browse/icons/term/painter-artist/)
|
|
365
|
+
(licensed under
|
|
366
|
+
[CC BY 3.0](https://creativecommons.org/licenses/by/3.0/deed.en))
|
|
367
|
+
as the background image.
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
## License
|
|
371
|
+
|
|
372
|
+
QRtsy is released under the [MIT License](LICENSE).
|
|
373
|
+
|
|
374
|
+
“QR Code” is a registered trademark of DENSO WAVE INCORPORATED.
|
|
375
|
+
|