New upstream version 1.2.1
Sascha Steinbiss
6 years ago
0 | Metadata-Version: 1.1 | |
1 | Name: PyQRCode | |
2 | Version: 1.2.1 | |
3 | Summary: A QR code generator written purely in Python with SVG, EPS, PNG and terminal output. | |
4 | Home-page: https://github.com/mnooner256/pyqrcode | |
5 | Author: Michael Nooner | |
6 | Author-email: mnooner256@gmail.com | |
7 | License: BSD | |
8 | Description: ======== | |
9 | PyQRCode | |
10 | ======== | |
11 | ||
12 | .. contents:: | |
13 | ||
14 | The pyqrcode module is a QR code generator that is simple to use and written | |
15 | in pure python. The module can automates most of the building process for | |
16 | creating QR codes. Most codes can be created using only two lines of code! | |
17 | ||
18 | Unlike other generators, all of the helpers can be controlled manually. You are | |
19 | free to set any or all of the properties of your QR code. | |
20 | ||
21 | QR codes can be saved as SVG, PNG (by using the | |
22 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module), and plain text. They can | |
23 | also be displayed directly in most Linux terminal emulators. PIL is | |
24 | not used to render the image files. | |
25 | ||
26 | The pyqrcode module attempts to follow the QR code standard as closely as | |
27 | possible. The terminology and the encodings used in pyqrcode come directly | |
28 | from the standard. This module also follows the algorithm laid out in the | |
29 | standard. | |
30 | ||
31 | **Homepage**: https://github.com/mnooner256/pyqrcode | |
32 | ||
33 | **Documentation**: http://pythonhosted.org/PyQRCode/ | |
34 | ||
35 | Requirements | |
36 | ============ | |
37 | ||
38 | The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may | |
39 | want to install `pypng <https://pypi.python.org/pypi/pypng/>`_ in order to | |
40 | render PNG files, but it is optional. Note, pypng is a pure python PNG writer | |
41 | which does not require any other libraries. | |
42 | ||
43 | Installation | |
44 | ============ | |
45 | ||
46 | Installation is simple. It can be installed from pip using the following | |
47 | command:: | |
48 | ||
49 | $ pip install pyqrcode | |
50 | ||
51 | Or from the terminal:: | |
52 | ||
53 | $ python setup.py install | |
54 | ||
55 | ||
56 | Usage | |
57 | ===== | |
58 | ||
59 | The pyqrcode module aims to be as simple to use as possible. Below is a simple | |
60 | example of creating a QR code for a URL. The code is rendered out as an svg | |
61 | file. | |
62 | :: | |
63 | ||
64 | >>> import pyqrcode | |
65 | >>> url = pyqrcode.create('http://uca.edu') | |
66 | >>> url.svg('uca-url.svg', scale=8) | |
67 | >>> url.eps('uca-url.eps', scale=2) | |
68 | >>> print(url.terminal(quiet_zone=1)) | |
69 | ||
70 | The pyqrcode module, while easy to use, is powerful. You can set every | |
71 | property of the QR code. If you install the optional | |
72 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module, you can | |
73 | render the code as a PNG image. Below is a more complex example:: | |
74 | ||
75 | >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary') | |
76 | >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc]) | |
77 | >>> big_code.show() | |
78 | ||
79 | Keywords: qrcode,qr | |
80 | Platform: UNKNOWN | |
81 | Classifier: Development Status :: 4 - Beta | |
82 | Classifier: Environment :: Console | |
83 | Classifier: Intended Audience :: Developers | |
84 | Classifier: License :: OSI Approved :: BSD License | |
85 | Classifier: Topic :: Software Development :: Libraries :: Python Modules | |
86 | Classifier: Natural Language :: English | |
87 | Classifier: Operating System :: OS Independent | |
88 | Classifier: Operating System :: POSIX | |
89 | Classifier: Operating System :: Microsoft :: Windows | |
90 | Classifier: Programming Language :: Python :: 3 | |
91 | Classifier: Programming Language :: Python :: 2.6 | |
92 | Classifier: Programming Language :: Python :: 2.7 |
0 | Metadata-Version: 1.1 | |
1 | Name: PyQRCode | |
2 | Version: 1.2.1 | |
3 | Summary: A QR code generator written purely in Python with SVG, EPS, PNG and terminal output. | |
4 | Home-page: https://github.com/mnooner256/pyqrcode | |
5 | Author: Michael Nooner | |
6 | Author-email: mnooner256@gmail.com | |
7 | License: BSD | |
8 | Description: ======== | |
9 | PyQRCode | |
10 | ======== | |
11 | ||
12 | .. contents:: | |
13 | ||
14 | The pyqrcode module is a QR code generator that is simple to use and written | |
15 | in pure python. The module can automates most of the building process for | |
16 | creating QR codes. Most codes can be created using only two lines of code! | |
17 | ||
18 | Unlike other generators, all of the helpers can be controlled manually. You are | |
19 | free to set any or all of the properties of your QR code. | |
20 | ||
21 | QR codes can be saved as SVG, PNG (by using the | |
22 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module), and plain text. They can | |
23 | also be displayed directly in most Linux terminal emulators. PIL is | |
24 | not used to render the image files. | |
25 | ||
26 | The pyqrcode module attempts to follow the QR code standard as closely as | |
27 | possible. The terminology and the encodings used in pyqrcode come directly | |
28 | from the standard. This module also follows the algorithm laid out in the | |
29 | standard. | |
30 | ||
31 | **Homepage**: https://github.com/mnooner256/pyqrcode | |
32 | ||
33 | **Documentation**: http://pythonhosted.org/PyQRCode/ | |
34 | ||
35 | Requirements | |
36 | ============ | |
37 | ||
38 | The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may | |
39 | want to install `pypng <https://pypi.python.org/pypi/pypng/>`_ in order to | |
40 | render PNG files, but it is optional. Note, pypng is a pure python PNG writer | |
41 | which does not require any other libraries. | |
42 | ||
43 | Installation | |
44 | ============ | |
45 | ||
46 | Installation is simple. It can be installed from pip using the following | |
47 | command:: | |
48 | ||
49 | $ pip install pyqrcode | |
50 | ||
51 | Or from the terminal:: | |
52 | ||
53 | $ python setup.py install | |
54 | ||
55 | ||
56 | Usage | |
57 | ===== | |
58 | ||
59 | The pyqrcode module aims to be as simple to use as possible. Below is a simple | |
60 | example of creating a QR code for a URL. The code is rendered out as an svg | |
61 | file. | |
62 | :: | |
63 | ||
64 | >>> import pyqrcode | |
65 | >>> url = pyqrcode.create('http://uca.edu') | |
66 | >>> url.svg('uca-url.svg', scale=8) | |
67 | >>> url.eps('uca-url.eps', scale=2) | |
68 | >>> print(url.terminal(quiet_zone=1)) | |
69 | ||
70 | The pyqrcode module, while easy to use, is powerful. You can set every | |
71 | property of the QR code. If you install the optional | |
72 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module, you can | |
73 | render the code as a PNG image. Below is a more complex example:: | |
74 | ||
75 | >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary') | |
76 | >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc]) | |
77 | >>> big_code.show() | |
78 | ||
79 | Keywords: qrcode,qr | |
80 | Platform: UNKNOWN | |
81 | Classifier: Development Status :: 4 - Beta | |
82 | Classifier: Environment :: Console | |
83 | Classifier: Intended Audience :: Developers | |
84 | Classifier: License :: OSI Approved :: BSD License | |
85 | Classifier: Topic :: Software Development :: Libraries :: Python Modules | |
86 | Classifier: Natural Language :: English | |
87 | Classifier: Operating System :: OS Independent | |
88 | Classifier: Operating System :: POSIX | |
89 | Classifier: Operating System :: Microsoft :: Windows | |
90 | Classifier: Programming Language :: Python :: 3 | |
91 | Classifier: Programming Language :: Python :: 2.6 | |
92 | Classifier: Programming Language :: Python :: 2.7 |
0 | README.rst | |
1 | setup.py | |
2 | PyQRCode.egg-info/PKG-INFO | |
3 | PyQRCode.egg-info/SOURCES.txt | |
4 | PyQRCode.egg-info/dependency_links.txt | |
5 | PyQRCode.egg-info/requires.txt | |
6 | PyQRCode.egg-info/top_level.txt | |
7 | pyqrcode/__init__.py | |
8 | pyqrcode/builder.py | |
9 | pyqrcode/tables.py⏎ |
0 | pyqrcode |
0 | ======== | |
1 | PyQRCode | |
2 | ======== | |
3 | ||
4 | .. contents:: | |
5 | ||
6 | The pyqrcode module is a QR code generator that is simple to use and written | |
7 | in pure python. The module can automates most of the building process for | |
8 | creating QR codes. Most codes can be created using only two lines of code! | |
9 | ||
10 | Unlike other generators, all of the helpers can be controlled manually. You are | |
11 | free to set any or all of the properties of your QR code. | |
12 | ||
13 | QR codes can be saved as SVG, PNG (by using the | |
14 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module), and plain text. They can | |
15 | also be displayed directly in most Linux terminal emulators. PIL is | |
16 | not used to render the image files. | |
17 | ||
18 | The pyqrcode module attempts to follow the QR code standard as closely as | |
19 | possible. The terminology and the encodings used in pyqrcode come directly | |
20 | from the standard. This module also follows the algorithm laid out in the | |
21 | standard. | |
22 | ||
23 | **Homepage**: https://github.com/mnooner256/pyqrcode | |
24 | ||
25 | **Documentation**: http://pythonhosted.org/PyQRCode/ | |
26 | ||
27 | Requirements | |
28 | ============ | |
29 | ||
30 | The pyqrcode module only requires Python 2.6, Python 2.7, or Python 3. You may | |
31 | want to install `pypng <https://pypi.python.org/pypi/pypng/>`_ in order to | |
32 | render PNG files, but it is optional. Note, pypng is a pure python PNG writer | |
33 | which does not require any other libraries. | |
34 | ||
35 | Installation | |
36 | ============ | |
37 | ||
38 | Installation is simple. It can be installed from pip using the following | |
39 | command:: | |
40 | ||
41 | $ pip install pyqrcode | |
42 | ||
43 | Or from the terminal:: | |
44 | ||
45 | $ python setup.py install | |
46 | ||
47 | ||
48 | Usage | |
49 | ===== | |
50 | ||
51 | The pyqrcode module aims to be as simple to use as possible. Below is a simple | |
52 | example of creating a QR code for a URL. The code is rendered out as an svg | |
53 | file. | |
54 | :: | |
55 | ||
56 | >>> import pyqrcode | |
57 | >>> url = pyqrcode.create('http://uca.edu') | |
58 | >>> url.svg('uca-url.svg', scale=8) | |
59 | >>> url.eps('uca-url.eps', scale=2) | |
60 | >>> print(url.terminal(quiet_zone=1)) | |
61 | ||
62 | The pyqrcode module, while easy to use, is powerful. You can set every | |
63 | property of the QR code. If you install the optional | |
64 | `pypng <https://pypi.python.org/pypi/pypng/>`_ module, you can | |
65 | render the code as a PNG image. Below is a more complex example:: | |
66 | ||
67 | >>> big_code = pyqrcode.create('0987654321', error='L', version=27, mode='binary') | |
68 | >>> big_code.png('code.png', scale=6, module_color=[0, 0, 0, 128], background=[0xff, 0xff, 0xcc]) | |
69 | >>> big_code.show() |
0 | # -*- coding: utf-8 -*- | |
1 | # Copyright (c) 2013, Michael Nooner | |
2 | # All rights reserved. | |
3 | ||
4 | # Redistribution and use in source and binary forms, with or without | |
5 | # modification, are permitted provided that the following conditions are met: | |
6 | # * Redistributions of source code must retain the above copyright | |
7 | # notice, this list of conditions and the following disclaimer. | |
8 | # * Redistributions in binary form must reproduce the above copyright | |
9 | # notice, this list of conditions and the following disclaimer in the | |
10 | # documentation and/or other materials provided with the distribution. | |
11 | # * Neither the name of the copyright holder nor the names of its | |
12 | # contributors may be used to endorse or promote products derived from | |
13 | # this software without specific prior written permission | |
14 | ||
15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 | # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | |
19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | """This module is used to create QR Codes. It is designed to be as simple and | |
26 | as possible. It does this by using sane defaults and autodetection to make | |
27 | creating a QR Code very simple. | |
28 | ||
29 | It is recommended that you use the :func:`pyqrcode.create` function to build the | |
30 | QRCode object. This results in cleaner looking code. | |
31 | ||
32 | Examples: | |
33 | >>> import pyqrcode | |
34 | >>> import sys | |
35 | >>> url = pyqrcode.create('http://uca.edu') | |
36 | >>> url.svg(sys.stdout, scale=1) | |
37 | >>> url.svg('uca.svg', scale=4) | |
38 | >>> number = pyqrcode.create(123456789012345) | |
39 | >>> number.png('big-number.png') | |
40 | """ | |
41 | ||
42 | #Imports required for 2.7 support | |
43 | from __future__ import absolute_import, division, print_function, with_statement, unicode_literals | |
44 | ||
45 | import pyqrcode.tables | |
46 | import pyqrcode.builder as builder | |
47 | ||
48 | try: | |
49 | str = unicode # Python 2 | |
50 | except NameError: | |
51 | pass | |
52 | ||
53 | def create(content, error='H', version=None, mode=None, encoding=None): | |
54 | """When creating a QR code only the content to be encoded is required, | |
55 | all the other properties of the code will be guessed based on the | |
56 | contents given. This function will return a :class:`QRCode` object. | |
57 | ||
58 | Unless you are familiar with QR code's inner workings | |
59 | it is recommended that you just specify the *content* and nothing else. | |
60 | However, there are cases where you may want to specify the various | |
61 | properties of the created code manually, this is what the other | |
62 | parameters do. Below, you will find a lengthy explanation of what | |
63 | each parameter is for. Note, the parameter names and values are taken | |
64 | directly from the standards. You may need to familiarize yourself | |
65 | with the terminology of QR codes for the names and their values to | |
66 | make sense. | |
67 | ||
68 | The *error* parameter sets the error correction level of the code. There | |
69 | are four levels defined by the standard. The first is level 'L' which | |
70 | allows for 7% of the code to be corrected. Second, is level 'M' which | |
71 | allows for 15% of the code to be corrected. Next, is level 'Q' which | |
72 | is the most common choice for error correction, it allow 25% of the | |
73 | code to be corrected. Finally, there is the highest level 'H' which | |
74 | allows for 30% of the code to be corrected. There are several ways to | |
75 | specify this parameter, you can use an upper or lower case letter, | |
76 | a float corresponding to the percentage of correction, or a string | |
77 | containing the percentage. See tables.modes for all the possible | |
78 | values. By default this parameter is set to 'H' which is the highest | |
79 | possible error correction, but it has the smallest available data | |
80 | capacity. | |
81 | ||
82 | The *version* parameter specifies the size and data capacity of the | |
83 | code. Versions are any integer between 1 and 40. Where version 1 is | |
84 | the smallest QR code, and version 40 is the largest. If this parameter | |
85 | is left unspecified, then the contents and error correction level will | |
86 | be used to guess the smallest possible QR code version that the | |
87 | content will fit inside of. You may want to specify this parameter | |
88 | for consistency when generating several QR codes with varying amounts | |
89 | of data. That way all of the generated codes would have the same size. | |
90 | ||
91 | The *mode* parameter specifies how the contents will be encoded. By | |
92 | default, the best possible mode for the contents is guessed. There | |
93 | are four possible modes. First, is 'numeric' which is | |
94 | used to encode integer numbers. Next, is 'alphanumeric' which is | |
95 | used to encode some ASCII characters. This mode uses only a limited | |
96 | set of characters. Most problematic is that it can only use upper case | |
97 | English characters, consequently, the content parameter will be | |
98 | subjected to str.upper() before encoding. See tables.ascii_codes for | |
99 | a complete list of available characters. The is 'kanji' mode can be | |
100 | used for Japanese characters, but only those that can be understood | |
101 | via the shift-jis string encoding. Finally, we then have 'binary' mode | |
102 | which just encodes the bytes directly into the QR code (this encoding | |
103 | is the least efficient). | |
104 | ||
105 | The *encoding* parameter specifies how the content will be interpreted. | |
106 | This parameter only matters if the *content* is a string, unicode, or | |
107 | byte array type. This parameter must be a valid encoding string or None. | |
108 | t will be passed the *content*'s encode/decode methods. | |
109 | """ | |
110 | return QRCode(content, error, version, mode, encoding) | |
111 | ||
112 | class QRCode: | |
113 | """This class represents a QR code. To use this class simply give the | |
114 | constructor a string representing the data to be encoded, it will then | |
115 | build a code in memory. You can then save it in various formats. Note, | |
116 | codes can be written out as PNG files but this requires the PyPNG module. | |
117 | You can find the PyPNG module at http://packages.python.org/pypng/. | |
118 | ||
119 | Examples: | |
120 | >>> from pyqrcode import QRCode | |
121 | >>> import sys | |
122 | >>> url = QRCode('http://uca.edu') | |
123 | >>> url.svg(sys.stdout, scale=1) | |
124 | >>> url.svg('uca.svg', scale=4) | |
125 | >>> number = QRCode(123456789012345) | |
126 | >>> number.png('big-number.png') | |
127 | ||
128 | .. note:: | |
129 | For what all of the parameters do, see the :func:`pyqrcode.create` | |
130 | function. | |
131 | """ | |
132 | def __init__(self, content, error='H', version=None, mode=None, | |
133 | encoding='iso-8859-1'): | |
134 | #Guess the mode of the code, this will also be used for | |
135 | #error checking | |
136 | guessed_content_type, encoding = self._detect_content_type(content, encoding) | |
137 | ||
138 | if encoding is None: | |
139 | encoding = 'iso-8859-1' | |
140 | ||
141 | #Store the encoding for use later | |
142 | if guessed_content_type == 'kanji': | |
143 | self.encoding = 'shiftjis' | |
144 | else: | |
145 | self.encoding = encoding | |
146 | ||
147 | if version is not None: | |
148 | if 1 <= version <= 40: | |
149 | self.version = version | |
150 | else: | |
151 | raise ValueError("Illegal version {0}, version must be between " | |
152 | "1 and 40.".format(version)) | |
153 | ||
154 | #Decode a 'byte array' contents into a string format | |
155 | if isinstance(content, bytes): | |
156 | self.data = content.decode(encoding) | |
157 | ||
158 | #Give a string an encoding | |
159 | elif hasattr(content, 'encode'): | |
160 | self.data = content.encode(self.encoding) | |
161 | ||
162 | #The contents are not a byte array or string, so | |
163 | #try naively converting to a string representation. | |
164 | else: | |
165 | self.data = str(content) # str == unicode in Py 2.x, see file head | |
166 | ||
167 | #Force a passed in mode to be lowercase | |
168 | if hasattr(mode, 'lower'): | |
169 | mode = mode.lower() | |
170 | ||
171 | #Check that the mode parameter is compatible with the contents | |
172 | if mode is None: | |
173 | #Use the guessed mode | |
174 | self.mode = guessed_content_type | |
175 | self.mode_num = tables.modes[self.mode] | |
176 | elif mode not in tables.modes.keys(): | |
177 | #Unknown mode | |
178 | raise ValueError('{0} is not a valid mode.'.format(mode)) | |
179 | elif guessed_content_type == 'binary' and \ | |
180 | tables.modes[mode] != tables.modes['binary']: | |
181 | #Binary is only guessed as a last resort, if the | |
182 | #passed in mode is not binary the data won't encode | |
183 | raise ValueError('The content provided cannot be encoded with ' | |
184 | 'the mode {}, it can only be encoded as ' | |
185 | 'binary.'.format(mode)) | |
186 | elif tables.modes[mode] == tables.modes['numeric'] and \ | |
187 | guessed_content_type != 'numeric': | |
188 | #If numeric encoding is requested make sure the data can | |
189 | #be encoded in that format | |
190 | raise ValueError('The content cannot be encoded as numeric.') | |
191 | elif tables.modes[mode] == tables.modes['kanji'] and \ | |
192 | guessed_content_type != 'kanji': | |
193 | raise ValueError('The content cannot be encoded as kanji.') | |
194 | else: | |
195 | #The data should encode with the passed in mode | |
196 | self.mode = mode | |
197 | self.mode_num = tables.modes[self.mode] | |
198 | ||
199 | #Check that the user passed in a valid error level | |
200 | if error in tables.error_level.keys(): | |
201 | self.error = tables.error_level[error] | |
202 | else: | |
203 | raise ValueError('{0} is not a valid error ' | |
204 | 'level.'.format(error)) | |
205 | ||
206 | #Guess the "best" version | |
207 | self.version = self._pick_best_fit(self.data) | |
208 | ||
209 | #If the user supplied a version, then check that it has | |
210 | #sufficient data capacity for the contents passed in | |
211 | if version: | |
212 | if version >= self.version: | |
213 | self.version = version | |
214 | else: | |
215 | raise ValueError('The data will not fit inside a version {} ' | |
216 | 'code with the given encoding and error ' | |
217 | 'level (the code must be at least a ' | |
218 | 'version {}).'.format(version, self.version)) | |
219 | ||
220 | #Build the QR code | |
221 | self.builder = builder.QRCodeBuilder(data=self.data, | |
222 | version=self.version, | |
223 | mode=self.mode, | |
224 | error=self.error) | |
225 | ||
226 | #Save the code for easier reference | |
227 | self.code = self.builder.code | |
228 | ||
229 | def __str__(self): | |
230 | return repr(self) | |
231 | ||
232 | def __unicode__(self): | |
233 | return self.__repr__() | |
234 | ||
235 | def __repr__(self): | |
236 | return "QRCode(content={0}, error='{1}', version={2}, mode='{3}')" \ | |
237 | .format(repr(self.data), self.error, self.version, self.mode) | |
238 | ||
239 | def _detect_content_type(self, content, encoding): | |
240 | """This method tries to auto-detect the type of the data. It first | |
241 | tries to see if the data is a valid integer, in which case it returns | |
242 | numeric. Next, it tests the data to see if it is 'alphanumeric.' QR | |
243 | Codes use a special table with very limited range of ASCII characters. | |
244 | The code's data is tested to make sure it fits inside this limited | |
245 | range. If all else fails, the data is determined to be of type | |
246 | 'binary.' | |
247 | ||
248 | Returns a tuple containing the detected mode and encoding. | |
249 | ||
250 | Note, encoding ECI is not yet implemented. | |
251 | """ | |
252 | def two_bytes(c): | |
253 | """Output two byte character code as a single integer.""" | |
254 | def next_byte(b): | |
255 | """Make sure that character code is an int. Python 2 and | |
256 | 3 compatibility. | |
257 | """ | |
258 | if not isinstance(b, int): | |
259 | return ord(b) | |
260 | else: | |
261 | return b | |
262 | ||
263 | #Go through the data by looping to every other character | |
264 | for i in range(0, len(c), 2): | |
265 | yield (next_byte(c[i]) << 8) | next_byte(c[i+1]) | |
266 | ||
267 | #See if the data is a number | |
268 | try: | |
269 | if str(content).isdigit(): | |
270 | return 'numeric', encoding | |
271 | except (TypeError, UnicodeError): | |
272 | pass | |
273 | ||
274 | #See if that data is alphanumeric based on the standards | |
275 | #special ASCII table | |
276 | valid_characters = ''.join(tables.ascii_codes.keys()) | |
277 | ||
278 | #Force the characters into a byte array | |
279 | valid_characters = valid_characters.encode('ASCII') | |
280 | ||
281 | try: | |
282 | if isinstance(content, bytes): | |
283 | c = content.decode('ASCII') | |
284 | else: | |
285 | c = str(content).encode('ASCII') | |
286 | ||
287 | if all(map(lambda x: x in valid_characters, c)): | |
288 | return 'alphanumeric', 'ASCII' | |
289 | ||
290 | #This occurs if the content does not contain ASCII characters. | |
291 | #Since the whole point of the if statement is to look for ASCII | |
292 | #characters, the resulting mode should not be alphanumeric. | |
293 | #Hence, this is not an error. | |
294 | except TypeError: | |
295 | pass | |
296 | except UnicodeError: | |
297 | pass | |
298 | ||
299 | try: | |
300 | if isinstance(content, bytes): | |
301 | if encoding is None: | |
302 | encoding = 'shiftjis' | |
303 | ||
304 | c = content.decode(encoding).encode('shiftjis') | |
305 | else: | |
306 | c = content.encode('shiftjis') | |
307 | ||
308 | #All kanji characters must be two bytes long, make sure the | |
309 | #string length is not odd. | |
310 | if len(c) % 2 != 0: | |
311 | return 'binary', encoding | |
312 | ||
313 | #Make sure the characters are actually in range. | |
314 | for asint in two_bytes(c): | |
315 | #Shift the two byte value as indicated by the standard | |
316 | if not (0x8140 <= asint <= 0x9FFC or | |
317 | 0xE040 <= asint <= 0xEBBF): | |
318 | return 'binary', encoding | |
319 | ||
320 | return 'kanji', encoding | |
321 | ||
322 | except UnicodeError: | |
323 | #This occurs if the content does not contain Shift JIS kanji | |
324 | #characters. Hence, the resulting mode should not be kanji. | |
325 | #This is not an error. | |
326 | pass | |
327 | ||
328 | #All of the other attempts failed. The content can only be binary. | |
329 | return 'binary', encoding | |
330 | ||
331 | def _pick_best_fit(self, content): | |
332 | """This method return the smallest possible QR code version number | |
333 | that will fit the specified data with the given error level. | |
334 | """ | |
335 | import math | |
336 | ||
337 | for version in range(1, 41): | |
338 | #Get the maximum possible capacity | |
339 | capacity = tables.data_capacity[version][self.error][self.mode_num] | |
340 | ||
341 | #Check the capacity | |
342 | #Kanji's count in the table is "characters" which are two bytes | |
343 | if (self.mode_num == tables.modes['kanji'] and | |
344 | capacity >= math.ceil(len(content) / 2)): | |
345 | return version | |
346 | if capacity >= len(content): | |
347 | return version | |
348 | ||
349 | raise ValueError('The data will not fit in any QR code version ' | |
350 | 'with the given encoding and error level.') | |
351 | ||
352 | def show(self, wait=1.2, scale=10, module_color=(0, 0, 0, 255), | |
353 | background=(255, 255, 255, 255), quiet_zone=4): | |
354 | """Displays this QR code. | |
355 | ||
356 | This method is mainly intended for debugging purposes. | |
357 | ||
358 | This method saves the output of the :py:meth:`png` method (with a default | |
359 | scaling factor of 10) to a temporary file and opens it with the | |
360 | standard PNG viewer application or within the standard webbrowser. The | |
361 | temporary file is deleted afterwards. | |
362 | ||
363 | If this method does not show any result, try to increase the `wait` | |
364 | parameter. This parameter specifies the time in seconds to wait till | |
365 | the temporary file is deleted. Note, that this method does not return | |
366 | until the provided amount of seconds (default: 1.2) has passed. | |
367 | ||
368 | The other parameters are simply passed on to the `png` method. | |
369 | """ | |
370 | import os | |
371 | import time | |
372 | import tempfile | |
373 | import webbrowser | |
374 | ||
375 | try: # Python 2 | |
376 | from urlparse import urljoin | |
377 | from urllib import pathname2url | |
378 | except ImportError: # Python 3 | |
379 | from urllib.parse import urljoin | |
380 | from urllib.request import pathname2url | |
381 | ||
382 | f = tempfile.NamedTemporaryFile('wb', suffix='.png', delete=False) | |
383 | self.png(f, scale=scale, module_color=module_color, | |
384 | background=background, quiet_zone=quiet_zone) | |
385 | f.close() | |
386 | webbrowser.open_new_tab(urljoin('file:', pathname2url(f.name))) | |
387 | time.sleep(wait) | |
388 | os.unlink(f.name) | |
389 | ||
390 | def get_png_size(self, scale=1, quiet_zone=4): | |
391 | """This is method helps users determine what *scale* to use when | |
392 | creating a PNG of this QR code. It is meant mostly to be used in the | |
393 | console to help the user determine the pixel size of the code | |
394 | using various scales. | |
395 | ||
396 | This method will return an integer representing the width and height of | |
397 | the QR code in pixels, as if it was drawn using the given *scale*. | |
398 | Because QR codes are square, the number represents both the width | |
399 | and height dimensions. | |
400 | ||
401 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
402 | should be. According to the standard this should be 4 modules. It is | |
403 | left settable because such a wide quiet zone is unnecessary in many | |
404 | applications where the QR code is not being printed. | |
405 | ||
406 | Example: | |
407 | >>> code = pyqrcode.QRCode("I don't like spam!") | |
408 | >>> print(code.get_png_size(1)) | |
409 | 31 | |
410 | >>> print(code.get_png_size(5)) | |
411 | 155 | |
412 | """ | |
413 | return builder._get_png_size(self.version, scale, quiet_zone) | |
414 | ||
415 | def png(self, file, scale=1, module_color=(0, 0, 0, 255), | |
416 | background=(255, 255, 255, 255), quiet_zone=4): | |
417 | """This method writes the QR code out as an PNG image. The resulting | |
418 | PNG has a bit depth of 1. The file parameter is used to specify where | |
419 | to write the image to. It can either be an writable stream or a | |
420 | file path. | |
421 | ||
422 | .. note:: | |
423 | This method depends on the pypng module to actually create the | |
424 | PNG file. | |
425 | ||
426 | This method will write the given *file* out as a PNG file. The file | |
427 | can be either a string file path, or a writable stream. The file | |
428 | will not be automatically closed if a stream is given. | |
429 | ||
430 | The *scale* parameter sets how large to draw a single module. By | |
431 | default one pixel is used to draw a single module. This may make the | |
432 | code too small to be read efficiently. Increasing the scale will make | |
433 | the code larger. Only integer scales are usable. This method will | |
434 | attempt to coerce the parameter into an integer (e.g. 2.5 will become 2, | |
435 | and '3' will become 3). You can use the :py:meth:`get_png_size` method | |
436 | to calculate the actual pixel size of the resulting PNG image. | |
437 | ||
438 | The *module_color* parameter sets what color to use for the encoded | |
439 | modules (the black part on most QR codes). The *background* parameter | |
440 | sets what color to use for the background (the white part on most | |
441 | QR codes). If either parameter is set, then both must be | |
442 | set or a ValueError is raised. Colors should be specified as either | |
443 | a list or a tuple of length 3 or 4. The components of the list must | |
444 | be integers between 0 and 255. The first three member give the RGB | |
445 | color. The fourth member gives the alpha component, where 0 is | |
446 | transparent and 255 is opaque. Note, many color | |
447 | combinations are unreadable by scanners, so be judicious. | |
448 | ||
449 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
450 | should be. According to the standard this should be 4 modules. It is | |
451 | left settable because such a wide quiet zone is unnecessary in many | |
452 | applications where the QR code is not being printed. | |
453 | ||
454 | Example: | |
455 | >>> code = pyqrcode.create('Are you suggesting coconuts migrate?') | |
456 | >>> code.png('swallow.png', scale=5) | |
457 | >>> code.png('swallow.png', scale=5, | |
458 | module_color=(0x66, 0x33, 0x0), #Dark brown | |
459 | background=(0xff, 0xff, 0xff, 0x88)) #50% transparent white | |
460 | """ | |
461 | builder._png(self.code, self.version, file, scale, | |
462 | module_color, background, quiet_zone) | |
463 | ||
464 | def png_as_base64_str(self, scale=1, module_color=(0, 0, 0, 255), | |
465 | background=(255, 255, 255, 255), quiet_zone=4): | |
466 | """This method uses the png render and returns the PNG image encoded as | |
467 | base64 string. This can be useful for creating dynamic PNG images for | |
468 | web development, since no file needs to be created. | |
469 | ||
470 | Example: | |
471 | >>> code = pyqrcode.create('Are you suggesting coconuts migrate?') | |
472 | >>> image_as_str = code.png_as_base64_str(scale=5) | |
473 | >>> html_img = '<img src="data:image/png;base64,{}">'.format(image_as_str) | |
474 | ||
475 | The parameters are passed directly to the :py:meth:`png` method. Refer | |
476 | to that method's documentation for the meaning behind the parameters. | |
477 | ||
478 | .. note:: | |
479 | This method depends on the pypng module to actually create the | |
480 | PNG image. | |
481 | ||
482 | """ | |
483 | import io | |
484 | import base64 | |
485 | ||
486 | with io.BytesIO() as virtual_file: | |
487 | self.png(file=virtual_file, scale=scale, module_color=module_color, | |
488 | background=background, quiet_zone=quiet_zone) | |
489 | image_as_str = base64.b64encode(virtual_file.getvalue()).decode("ascii") | |
490 | return image_as_str | |
491 | ||
492 | def xbm(self, scale=1, quiet_zone=4): | |
493 | """Returns a string representing an XBM image of the QR code. | |
494 | The XBM format is a black and white image format that looks like a | |
495 | C header file. | |
496 | ||
497 | Because displaying QR codes in Tkinter is the | |
498 | primary use case for this renderer, this method does not take a file | |
499 | parameter. Instead it retuns the rendered QR code data as a string. | |
500 | ||
501 | Example of using this renderer with Tkinter: | |
502 | >>> import pyqrcode | |
503 | >>> import tkinter | |
504 | >>> code = pyqrcode.create('Knights who say ni!') | |
505 | >>> code_xbm = code.xbm(scale=5) | |
506 | >>> | |
507 | >>> top = tkinter.Tk() | |
508 | >>> code_bmp = tkinter.BitmapImage(data=code_xbm) | |
509 | >>> code_bmp.config(foreground="black") | |
510 | >>> code_bmp.config(background="white") | |
511 | >>> label = tkinter.Label(image=code_bmp) | |
512 | >>> label.pack() | |
513 | ||
514 | ||
515 | The *scale* parameter sets how large to draw a single module. By | |
516 | default one pixel is used to draw a single module. This may make the | |
517 | code too small to be read efficiently. Increasing the scale will make | |
518 | the code larger. Only integer scales are usable. This method will | |
519 | attempt to coerce the parameter into an integer (e.g. 2.5 will become 2, | |
520 | and '3' will become 3). You can use the :py:meth:`get_png_size` method | |
521 | to calculate the actual pixel size of this image when displayed. | |
522 | ||
523 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
524 | should be. According to the standard this should be 4 modules. It is | |
525 | left settable because such a wide quiet zone is unnecessary in many | |
526 | applications where the QR code is not being printed. | |
527 | """ | |
528 | return builder._xbm(self.code, scale, quiet_zone) | |
529 | ||
530 | def svg(self, file, scale=1, module_color='#000', background=None, | |
531 | quiet_zone=4, xmldecl=True, svgns=True, title=None, | |
532 | svgclass='pyqrcode', lineclass='pyqrline', omithw=False, | |
533 | debug=False): | |
534 | """This method writes the QR code out as an SVG document. The | |
535 | code is drawn by drawing only the modules corresponding to a 1. They | |
536 | are drawn using a line, such that contiguous modules in a row | |
537 | are drawn with a single line. | |
538 | ||
539 | The *file* parameter is used to specify where to write the document | |
540 | to. It can either be a writable stream or a file path. | |
541 | ||
542 | The *scale* parameter sets how large to draw | |
543 | a single module. By default one pixel is used to draw a single | |
544 | module. This may make the code too small to be read efficiently. | |
545 | Increasing the scale will make the code larger. Unlike the png() method, | |
546 | this method will accept fractional scales (e.g. 2.5). | |
547 | ||
548 | Note, three things are done to make the code more appropriate for | |
549 | embedding in a HTML document. The "white" part of the code is actually | |
550 | transparent. The code itself has a class given by *svgclass* parameter. | |
551 | The path making up the QR code uses the class set using the *lineclass*. | |
552 | These should make the code easier to style using CSS. | |
553 | ||
554 | By default the output of this function is a complete SVG document. If | |
555 | only the code itself is desired, set the *xmldecl* to false. This will | |
556 | result in a fragment that contains only the "drawn" portion of the code. | |
557 | Likewise, you can set the *title* of the document. The SVG name space | |
558 | attribute can be suppressed by setting *svgns* to False. | |
559 | ||
560 | When True the *omithw* indicates if width and height attributes should | |
561 | be omitted. If these attributes are omitted, a ``viewBox`` attribute | |
562 | will be added to the document. | |
563 | ||
564 | You can also set the colors directly using the *module_color* and | |
565 | *background* parameters. The *module_color* parameter sets what color to | |
566 | use for the data modules (the black part on most QR codes). The | |
567 | *background* parameter sets what color to use for the background (the | |
568 | white part on most QR codes). The parameters can be set to any valid | |
569 | SVG or HTML color. If the background is set to None, then no background | |
570 | will be drawn, i.e. the background will be transparent. Note, many color | |
571 | combinations are unreadable by scanners, so be careful. | |
572 | ||
573 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
574 | should be. According to the standard this should be 4 modules. It is | |
575 | left settable because such a wide quiet zone is unnecessary in many | |
576 | applications where the QR code is not being printed. | |
577 | ||
578 | Example: | |
579 | >>> code = pyqrcode.create('Hello. Uhh, can we have your liver?') | |
580 | >>> code.svg('live-organ-transplants.svg', 3.6) | |
581 | >>> code.svg('live-organ-transplants.svg', scale=4, | |
582 | module_color='brown', background='0xFFFFFF') | |
583 | """ | |
584 | builder._svg(self.code, self.version, file, scale=scale, | |
585 | module_color=module_color, background=background, | |
586 | quiet_zone=quiet_zone, xmldecl=xmldecl, svgns=svgns, | |
587 | title=title, svgclass=svgclass, lineclass=lineclass, | |
588 | omithw=omithw, debug=debug) | |
589 | ||
590 | def eps(self, file, scale=1, module_color=(0, 0, 0), | |
591 | background=None, quiet_zone=4): | |
592 | """This method writes the QR code out as an EPS document. The | |
593 | code is drawn by only writing the data modules corresponding to a 1. | |
594 | They are drawn using a line, such that contiguous modules in a row | |
595 | are drawn with a single line. | |
596 | ||
597 | The *file* parameter is used to specify where to write the document | |
598 | to. It can either be a writable (text) stream or a file path. | |
599 | ||
600 | The *scale* parameter sets how large to draw a single module. By | |
601 | default one point (1/72 inch) is used to draw a single module. This may | |
602 | make the code to small to be read efficiently. Increasing the scale | |
603 | will make the code larger. This method will accept fractional scales | |
604 | (e.g. 2.5). | |
605 | ||
606 | The *module_color* parameter sets the color of the data modules. The | |
607 | *background* parameter sets the background (page) color to use. They | |
608 | are specified as either a triple of floats, e.g. (0.5, 0.5, 0.5), or a | |
609 | triple of integers, e.g. (128, 128, 128). The default *module_color* is | |
610 | black. The default *background* color is no background at all. | |
611 | ||
612 | The *quiet_zone* parameter sets how large to draw the border around | |
613 | the code. As per the standard, the default value is 4 modules. | |
614 | ||
615 | Examples: | |
616 | >>> qr = pyqrcode.create('Hello world') | |
617 | >>> qr.eps('hello-world.eps', scale=2.5, module_color='#36C') | |
618 | >>> qr.eps('hello-world2.eps', background='#eee') | |
619 | >>> out = io.StringIO() | |
620 | >>> qr.eps(out, module_color=(.4, .4, .4)) | |
621 | """ | |
622 | builder._eps(self.code, self.version, file, scale, module_color, | |
623 | background, quiet_zone) | |
624 | ||
625 | def terminal(self, module_color='default', background='reverse', | |
626 | quiet_zone=4): | |
627 | """This method returns a string containing ASCII escape codes, | |
628 | such that if printed to a compatible terminal, it will display | |
629 | a vaild QR code. The code is printed using ASCII escape | |
630 | codes that alter the coloring of the background. | |
631 | ||
632 | The *module_color* parameter sets what color to | |
633 | use for the data modules (the black part on most QR codes). | |
634 | Likewise, the *background* parameter sets what color to use | |
635 | for the background (the white part on most QR codes). | |
636 | ||
637 | There are two options for colors. The first, and most widely | |
638 | supported, is to use the 8 or 16 color scheme. This scheme uses | |
639 | eight to sixteen named colors. The following colors are | |
640 | supported the most widely supported: black, red, green, | |
641 | yellow, blue, magenta, and cyan. There are an some additional | |
642 | named colors that are supported by most terminals: light gray, | |
643 | dark gray, light red, light green, light blue, light yellow, | |
644 | light magenta, light cyan, and white. | |
645 | ||
646 | There are two special named colors. The first is the | |
647 | "default" color. This color is the color the background of | |
648 | the terminal is set to. The next color is the "reverse" | |
649 | color. This is not really a color at all but a special | |
650 | property that will reverse the current color. These two colors | |
651 | are the default values for *module_color* and *background* | |
652 | respectively. These values should work on most terminals. | |
653 | ||
654 | Finally, there is one more way to specify the color. Some | |
655 | terminals support 256 colors. The actual colors displayed in the | |
656 | terminal is system dependent. This is the least transportable option. | |
657 | To use the 256 color scheme set *module_color* and/or | |
658 | *background* to a number between 0 and 256. | |
659 | ||
660 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
661 | should be. According to the standard this should be 4 modules. It is | |
662 | left settable because such a wide quiet zone is unnecessary in many | |
663 | applications. | |
664 | ||
665 | Example: | |
666 | >>> code = pyqrcode.create('Example') | |
667 | >>> text = code.terminal() | |
668 | >>> print(text) | |
669 | """ | |
670 | return builder._terminal(self.code, module_color, background, | |
671 | quiet_zone) | |
672 | ||
673 | def text(self, quiet_zone=4): | |
674 | """This method returns a string based representation of the QR code. | |
675 | The data modules are represented by 1's and the background modules are | |
676 | represented by 0's. The main purpose of this method is to act a | |
677 | starting point for users to create their own renderers. | |
678 | ||
679 | The *quiet_zone* parameter sets how wide the quiet zone around the code | |
680 | should be. According to the standard this should be 4 modules. It is | |
681 | left settable because such a wide quiet zone is unnecessary in many | |
682 | applications. | |
683 | ||
684 | Example: | |
685 | >>> code = pyqrcode.create('Example') | |
686 | >>> text = code.text() | |
687 | >>> print(text) | |
688 | """ | |
689 | return builder._text(self.code, quiet_zone) | |
690 |
0 | # -*- coding: utf-8 -*- | |
1 | # Copyright (c) 2013, Michael Nooner | |
2 | # All rights reserved. | |
3 | # | |
4 | # Redistribution and use in source and binary forms, with or without | |
5 | # modification, are permitted provided that the following conditions are met: | |
6 | # * Redistributions of source code must retain the above copyright | |
7 | # notice, this list of conditions and the following disclaimer. | |
8 | # * Redistributions in binary form must reproduce the above copyright | |
9 | # notice, this list of conditions and the following disclaimer in the | |
10 | # documentation and/or other materials provided with the distribution. | |
11 | # * Neither the name of the copyright holder nor the names of its | |
12 | # contributors may be used to endorse or promote products derived from | |
13 | # this software without specific prior written permission | |
14 | # | |
15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 | # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | |
19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | """This module does the actual generation of the QR codes. The QRCodeBuilder | |
26 | builds the code. While the various output methods draw the code into a file. | |
27 | """ | |
28 | ||
29 | #Imports required for 2.x support | |
30 | from __future__ import absolute_import, division, print_function, with_statement, unicode_literals | |
31 | ||
32 | import pyqrcode.tables as tables | |
33 | import io | |
34 | import itertools | |
35 | import math | |
36 | ||
37 | class QRCodeBuilder: | |
38 | """This class generates a QR code based on the standard. It is meant to | |
39 | be used internally, not by users!!! | |
40 | ||
41 | This class implements the tutorials found at: | |
42 | ||
43 | * http://www.thonky.com/qr-code-tutorial/ | |
44 | ||
45 | * http://www.matchadesign.com/blog/qr-code-demystified-part-6/ | |
46 | ||
47 | This class also uses the standard, which can be read online at: | |
48 | http://raidenii.net/files/datasheets/misc/qr_code.pdf | |
49 | ||
50 | Test codes were tested against: | |
51 | http://zxing.org/w/decode.jspx | |
52 | ||
53 | Also, reference codes were generat/ed at: | |
54 | http://www.morovia.com/free-online-barcode-generator/qrcode-maker.php | |
55 | http://demos.telerik.com/aspnet-ajax/barcode/examples/qrcode/defaultcs.aspx | |
56 | ||
57 | QR code Debugger: | |
58 | http://qrlogo.kaarposoft.dk/qrdecode.html | |
59 | """ | |
60 | def __init__(self, data, version, mode, error): | |
61 | """See :py:class:`pyqrcode.QRCode` for information on the parameters.""" | |
62 | #Set what data we are going to use to generate | |
63 | #the QR code | |
64 | self.data = data | |
65 | ||
66 | #Check that the user passed in a valid mode | |
67 | if mode in tables.modes: | |
68 | self.mode = tables.modes[mode] | |
69 | else: | |
70 | raise ValueError('{0} is not a valid mode.'.format(mode)) | |
71 | ||
72 | #Check that the user passed in a valid error level | |
73 | if error in tables.error_level: | |
74 | self.error = tables.error_level[error] | |
75 | else: | |
76 | raise ValueError('{0} is not a valid error ' | |
77 | 'level.'.format(error)) | |
78 | ||
79 | if 1 <= version <= 40: | |
80 | self.version = version | |
81 | else: | |
82 | raise ValueError("Illegal version {0}, version must be between " | |
83 | "1 and 40.".format(version)) | |
84 | ||
85 | #Look up the proper row for error correction code words | |
86 | self.error_code_words = tables.eccwbi[version][self.error] | |
87 | ||
88 | #This property will hold the binary string as it is built | |
89 | self.buffer = io.StringIO() | |
90 | ||
91 | #Create the binary data block | |
92 | self.add_data() | |
93 | ||
94 | #Create the actual QR code | |
95 | self.make_code() | |
96 | ||
97 | def grouper(self, n, iterable, fillvalue=None): | |
98 | """This generator yields a set of tuples, where the | |
99 | iterable is broken into n sized chunks. If the | |
100 | iterable is not evenly sized then fillvalue will | |
101 | be appended to the last tuple to make up the difference. | |
102 | ||
103 | This function is copied from the standard docs on | |
104 | itertools. | |
105 | """ | |
106 | args = [iter(iterable)] * n | |
107 | if hasattr(itertools, 'zip_longest'): | |
108 | return itertools.zip_longest(*args, fillvalue=fillvalue) | |
109 | return itertools.izip_longest(*args, fillvalue=fillvalue) | |
110 | ||
111 | def binary_string(self, data, length): | |
112 | """This method returns a string of length n that is the binary | |
113 | representation of the given data. This function is used to | |
114 | basically create bit fields of a given size. | |
115 | """ | |
116 | return '{{0:0{0}b}}'.format(length).format(int(data)) | |
117 | ||
118 | def get_data_length(self): | |
119 | """QR codes contain a "data length" field. This method creates this | |
120 | field. A binary string representing the appropriate length is | |
121 | returned. | |
122 | """ | |
123 | ||
124 | #The "data length" field varies by the type of code and its mode. | |
125 | #discover how long the "data length" field should be. | |
126 | if 1 <= self.version <= 9: | |
127 | max_version = 9 | |
128 | elif 10 <= self.version <= 26: | |
129 | max_version = 26 | |
130 | elif 27 <= self.version <= 40: | |
131 | max_version = 40 | |
132 | ||
133 | data_length = tables.data_length_field[max_version][self.mode] | |
134 | ||
135 | if self.mode != tables.modes['kanji']: | |
136 | length_string = self.binary_string(len(self.data), data_length) | |
137 | else: | |
138 | length_string = self.binary_string(len(self.data) / 2, data_length) | |
139 | ||
140 | if len(length_string) > data_length: | |
141 | raise ValueError('The supplied data will not fit ' | |
142 | 'within this version of a QRCode.') | |
143 | return length_string | |
144 | ||
145 | def encode(self): | |
146 | """This method encodes the data into a binary string using | |
147 | the appropriate algorithm specified by the mode. | |
148 | """ | |
149 | if self.mode == tables.modes['alphanumeric']: | |
150 | encoded = self.encode_alphanumeric() | |
151 | elif self.mode == tables.modes['numeric']: | |
152 | encoded = self.encode_numeric() | |
153 | elif self.mode == tables.modes['binary']: | |
154 | encoded = self.encode_bytes() | |
155 | elif self.mode == tables.modes['kanji']: | |
156 | encoded = self.encode_kanji() | |
157 | return encoded | |
158 | ||
159 | def encode_alphanumeric(self): | |
160 | """This method encodes the QR code's data if its mode is | |
161 | alphanumeric. It returns the data encoded as a binary string. | |
162 | """ | |
163 | #Convert the string to upper case | |
164 | self.data = self.data.upper() | |
165 | ||
166 | #Change the data such that it uses a QR code ascii table | |
167 | ascii = [] | |
168 | for char in self.data: | |
169 | if isinstance(char, int): | |
170 | ascii.append(tables.ascii_codes[chr(char)]) | |
171 | else: | |
172 | ascii.append(tables.ascii_codes[char]) | |
173 | ||
174 | #Now perform the algorithm that will make the ascii into bit fields | |
175 | with io.StringIO() as buf: | |
176 | for (a,b) in self.grouper(2, ascii): | |
177 | if b is not None: | |
178 | buf.write(self.binary_string((45*a)+b, 11)) | |
179 | else: | |
180 | #This occurs when there is an odd number | |
181 | #of characters in the data | |
182 | buf.write(self.binary_string(a, 6)) | |
183 | ||
184 | #Return the binary string | |
185 | return buf.getvalue() | |
186 | ||
187 | def encode_numeric(self): | |
188 | """This method encodes the QR code's data if its mode is | |
189 | numeric. It returns the data encoded as a binary string. | |
190 | """ | |
191 | with io.StringIO() as buf: | |
192 | #Break the number into groups of three digits | |
193 | for triplet in self.grouper(3, self.data): | |
194 | number = '' | |
195 | for digit in triplet: | |
196 | if isinstance(digit, int): | |
197 | digit = chr(digit) | |
198 | ||
199 | #Only build the string if digit is not None | |
200 | if digit: | |
201 | number = ''.join([number, digit]) | |
202 | else: | |
203 | break | |
204 | ||
205 | #If the number is one digits, make a 4 bit field | |
206 | if len(number) == 1: | |
207 | bin = self.binary_string(number, 4) | |
208 | ||
209 | #If the number is two digits, make a 7 bit field | |
210 | elif len(number) == 2: | |
211 | bin = self.binary_string(number, 7) | |
212 | ||
213 | #Three digit numbers use a 10 bit field | |
214 | else: | |
215 | bin = self.binary_string(number, 10) | |
216 | ||
217 | buf.write(bin) | |
218 | return buf.getvalue() | |
219 | ||
220 | def encode_bytes(self): | |
221 | """This method encodes the QR code's data if its mode is | |
222 | 8 bit mode. It returns the data encoded as a binary string. | |
223 | """ | |
224 | with io.StringIO() as buf: | |
225 | for char in self.data: | |
226 | if not isinstance(char, int): | |
227 | buf.write('{{0:0{0}b}}'.format(8).format(ord(char))) | |
228 | else: | |
229 | buf.write('{{0:0{0}b}}'.format(8).format(char)) | |
230 | return buf.getvalue() | |
231 | ||
232 | def encode_kanji(self): | |
233 | """This method encodes the QR code's data if its mode is | |
234 | kanji. It returns the data encoded as a binary string. | |
235 | """ | |
236 | def two_bytes(data): | |
237 | """Output two byte character code as a single integer.""" | |
238 | def next_byte(b): | |
239 | """Make sure that character code is an int. Python 2 and | |
240 | 3 compatibility. | |
241 | """ | |
242 | if not isinstance(b, int): | |
243 | return ord(b) | |
244 | else: | |
245 | return b | |
246 | ||
247 | #Go through the data by looping to every other character | |
248 | for i in range(0, len(data), 2): | |
249 | yield (next_byte(data[i]) << 8) | next_byte(data[i+1]) | |
250 | ||
251 | #Force the data into Kanji encoded bytes | |
252 | if isinstance(self.data, bytes): | |
253 | data = self.data.decode('shiftjis').encode('shiftjis') | |
254 | else: | |
255 | data = self.data.encode('shiftjis') | |
256 | ||
257 | #Now perform the algorithm that will make the kanji into 13 bit fields | |
258 | with io.StringIO() as buf: | |
259 | for asint in two_bytes(data): | |
260 | #Shift the two byte value as indicated by the standard | |
261 | if 0x8140 <= asint <= 0x9FFC: | |
262 | difference = asint - 0x8140 | |
263 | elif 0xE040 <= asint <= 0xEBBF: | |
264 | difference = asint - 0xC140 | |
265 | ||
266 | #Split the new value into most and least significant bytes | |
267 | msb = (difference >> 8) | |
268 | lsb = (difference & 0x00FF) | |
269 | ||
270 | #Calculate the actual 13 bit binary value | |
271 | buf.write('{0:013b}'.format((msb * 0xC0) + lsb)) | |
272 | #Return the binary string | |
273 | return buf.getvalue() | |
274 | ||
275 | ||
276 | def add_data(self): | |
277 | """This function properly constructs a QR code's data string. It takes | |
278 | into account the interleaving pattern required by the standard. | |
279 | """ | |
280 | #Encode the data into a QR code | |
281 | self.buffer.write(self.binary_string(self.mode, 4)) | |
282 | self.buffer.write(self.get_data_length()) | |
283 | self.buffer.write(self.encode()) | |
284 | ||
285 | #Converts the buffer into "code word" integers. | |
286 | #The online debugger outputs them this way, makes | |
287 | #for easier comparisons. | |
288 | #s = self.buffer.getvalue() | |
289 | #for i in range(0, len(s), 8): | |
290 | # print(int(s[i:i+8], 2), end=',') | |
291 | #print() | |
292 | ||
293 | #Fix for issue #3: https://github.com/mnooner256/pyqrcode/issues/3# | |
294 | #I was performing the terminate_bits() part in the encoding. | |
295 | #As per the standard, terminating bits are only supposed to | |
296 | #be added after the bit stream is complete. I took that to | |
297 | #mean after the encoding, but actually it is after the entire | |
298 | #bit stream has been constructed. | |
299 | bits = self.terminate_bits(self.buffer.getvalue()) | |
300 | if bits is not None: | |
301 | self.buffer.write(bits) | |
302 | ||
303 | #delimit_words and add_words can return None | |
304 | add_bits = self.delimit_words() | |
305 | if add_bits: | |
306 | self.buffer.write(add_bits) | |
307 | ||
308 | fill_bytes = self.add_words() | |
309 | if fill_bytes: | |
310 | self.buffer.write(fill_bytes) | |
311 | ||
312 | #Get a numeric representation of the data | |
313 | data = [int(''.join(x),2) | |
314 | for x in self.grouper(8, self.buffer.getvalue())] | |
315 | ||
316 | #This is the error information for the code | |
317 | error_info = tables.eccwbi[self.version][self.error] | |
318 | ||
319 | #This will hold our data blocks | |
320 | data_blocks = [] | |
321 | ||
322 | #This will hold our error blocks | |
323 | error_blocks = [] | |
324 | ||
325 | #Some codes have the data sliced into two different sized blocks | |
326 | #for example, first two 14 word sized blocks, then four 15 word | |
327 | #sized blocks. This means that slicing size can change over time. | |
328 | data_block_sizes = [error_info[2]] * error_info[1] | |
329 | if error_info[3] != 0: | |
330 | data_block_sizes.extend([error_info[4]] * error_info[3]) | |
331 | ||
332 | #For every block of data, slice the data into the appropriate | |
333 | #sized block | |
334 | current_byte = 0 | |
335 | for n_data_blocks in data_block_sizes: | |
336 | data_blocks.append(data[current_byte:current_byte+n_data_blocks]) | |
337 | current_byte += n_data_blocks | |
338 | ||
339 | #I am not sure about the test after the "and". This was added to | |
340 | #fix a bug where after delimit_words padded the bit stream, a zero | |
341 | #byte ends up being added. After checking around, it seems this extra | |
342 | #byte is supposed to be chopped off, but I cannot find that in the | |
343 | #standard! I am adding it to solve the bug, I believe it is correct. | |
344 | if current_byte < len(data): | |
345 | raise ValueError('Too much data for this code version.') | |
346 | ||
347 | #DEBUG CODE!!!! | |
348 | #Print out the data blocks | |
349 | #print('Data Blocks:\n{0}'.format(data_blocks)) | |
350 | ||
351 | #Calculate the error blocks | |
352 | for n, block in enumerate(data_blocks): | |
353 | error_blocks.append(self.make_error_block(block, n)) | |
354 | ||
355 | #DEBUG CODE!!!! | |
356 | #Print out the error blocks | |
357 | #print('Error Blocks:\n{0}'.format(error_blocks)) | |
358 | ||
359 | #Buffer we will write our data blocks into | |
360 | data_buffer = io.StringIO() | |
361 | ||
362 | #Add the data blocks | |
363 | #Write the buffer such that: block 1 byte 1, block 2 byte 1, etc. | |
364 | largest_block = max(error_info[2], error_info[4])+error_info[0] | |
365 | for i in range(largest_block): | |
366 | for block in data_blocks: | |
367 | if i < len(block): | |
368 | data_buffer.write(self.binary_string(block[i], 8)) | |
369 | ||
370 | #Add the error code blocks. | |
371 | #Write the buffer such that: block 1 byte 1, block 2 byte 2, etc. | |
372 | for i in range(error_info[0]): | |
373 | for block in error_blocks: | |
374 | data_buffer.write(self.binary_string(block[i], 8)) | |
375 | ||
376 | self.buffer = data_buffer | |
377 | ||
378 | def terminate_bits(self, payload): | |
379 | """This method adds zeros to the end of the encoded data so that the | |
380 | encoded data is of the correct length. It returns a binary string | |
381 | containing the bits to be added. | |
382 | """ | |
383 | data_capacity = tables.data_capacity[self.version][self.error][0] | |
384 | ||
385 | if len(payload) > data_capacity: | |
386 | raise ValueError('The supplied data will not fit ' | |
387 | 'within this version of a QR code.') | |
388 | ||
389 | #We must add up to 4 zeros to make up for any shortfall in the | |
390 | #length of the data field. | |
391 | if len(payload) == data_capacity: | |
392 | return None | |
393 | elif len(payload) <= data_capacity-4: | |
394 | bits = self.binary_string(0,4) | |
395 | else: | |
396 | #Make up any shortfall need with less than 4 zeros | |
397 | bits = self.binary_string(0, data_capacity - len(payload)) | |
398 | ||
399 | return bits | |
400 | ||
401 | def delimit_words(self): | |
402 | """This method takes the existing encoded binary string | |
403 | and returns a binary string that will pad it such that | |
404 | the encoded string contains only full bytes. | |
405 | """ | |
406 | bits_short = 8 - (len(self.buffer.getvalue()) % 8) | |
407 | ||
408 | #The string already falls on an byte boundary do nothing | |
409 | if bits_short == 0 or bits_short == 8: | |
410 | return None | |
411 | else: | |
412 | return self.binary_string(0, bits_short) | |
413 | ||
414 | def add_words(self): | |
415 | """The data block must fill the entire data capacity of the QR code. | |
416 | If we fall short, then we must add bytes to the end of the encoded | |
417 | data field. The value of these bytes are specified in the standard. | |
418 | """ | |
419 | ||
420 | data_blocks = len(self.buffer.getvalue()) // 8 | |
421 | total_blocks = tables.data_capacity[self.version][self.error][0] // 8 | |
422 | needed_blocks = total_blocks - data_blocks | |
423 | ||
424 | if needed_blocks == 0: | |
425 | return None | |
426 | ||
427 | #This will return item1, item2, item1, item2, etc. | |
428 | block = itertools.cycle(['11101100', '00010001']) | |
429 | ||
430 | #Create a string of the needed blocks | |
431 | return ''.join([next(block) for x in range(needed_blocks)]) | |
432 | ||
433 | def make_error_block(self, block, block_number): | |
434 | """This function constructs the error correction block of the | |
435 | given data block. This is *very complicated* process. To | |
436 | understand the code you need to read: | |
437 | ||
438 | * http://www.thonky.com/qr-code-tutorial/part-2-error-correction/ | |
439 | * http://www.matchadesign.com/blog/qr-code-demystified-part-4/ | |
440 | """ | |
441 | #Get the error information from the standards table | |
442 | error_info = tables.eccwbi[self.version][self.error] | |
443 | ||
444 | #This is the number of 8-bit words per block | |
445 | if block_number < error_info[1]: | |
446 | code_words_per_block = error_info[2] | |
447 | else: | |
448 | code_words_per_block = error_info[4] | |
449 | ||
450 | #This is the size of the error block | |
451 | error_block_size = error_info[0] | |
452 | ||
453 | #Copy the block as the message polynomial coefficients | |
454 | mp_co = block[:] | |
455 | ||
456 | #Add the error blocks to the message polynomial | |
457 | mp_co.extend([0] * (error_block_size)) | |
458 | ||
459 | #Get the generator polynomial | |
460 | generator = tables.generator_polynomials[error_block_size] | |
461 | ||
462 | #This will hold the temporary sum of the message coefficient and the | |
463 | #generator polynomial | |
464 | gen_result = [0] * len(generator) | |
465 | ||
466 | #Go through every code word in the block | |
467 | for i in range(code_words_per_block): | |
468 | #Get the first coefficient from the message polynomial | |
469 | coefficient = mp_co.pop(0) | |
470 | ||
471 | #Skip coefficients that are zero | |
472 | if coefficient == 0: | |
473 | continue | |
474 | else: | |
475 | #Turn the coefficient into an alpha exponent | |
476 | alpha_exp = tables.galois_antilog[coefficient] | |
477 | ||
478 | #Add the alpha to the generator polynomial | |
479 | for n in range(len(generator)): | |
480 | gen_result[n] = alpha_exp + generator[n] | |
481 | if gen_result[n] > 255: | |
482 | gen_result[n] = gen_result[n] % 255 | |
483 | ||
484 | #Convert the alpha notation back into coefficients | |
485 | gen_result[n] = tables.galois_log[gen_result[n]] | |
486 | ||
487 | #XOR the sum with the message coefficients | |
488 | mp_co[n] = gen_result[n] ^ mp_co[n] | |
489 | ||
490 | #Pad the end of the error blocks with zeros if needed | |
491 | if len(mp_co) < code_words_per_block: | |
492 | mp_co.extend([0] * (code_words_per_block - len(mp_co))) | |
493 | ||
494 | return mp_co | |
495 | ||
496 | def make_code(self): | |
497 | """This method returns the best possible QR code.""" | |
498 | from copy import deepcopy | |
499 | ||
500 | #Get the size of the underlying matrix | |
501 | matrix_size = tables.version_size[self.version] | |
502 | ||
503 | #Create a template matrix we will build the codes with | |
504 | row = [' ' for x in range(matrix_size)] | |
505 | template = [deepcopy(row) for x in range(matrix_size)] | |
506 | ||
507 | #Add mandatory information to the template | |
508 | self.add_detection_pattern(template) | |
509 | self.add_position_pattern(template) | |
510 | self.add_version_pattern(template) | |
511 | ||
512 | #Create the various types of masks of the template | |
513 | self.masks = self.make_masks(template) | |
514 | ||
515 | self.best_mask = self.choose_best_mask() | |
516 | self.code = self.masks[self.best_mask] | |
517 | ||
518 | def add_detection_pattern(self, m): | |
519 | """This method add the detection patterns to the QR code. This lets | |
520 | the scanner orient the pattern. It is required for all QR codes. | |
521 | The detection pattern consists of three boxes located at the upper | |
522 | left, upper right, and lower left corners of the matrix. Also, two | |
523 | special lines called the timing pattern is also necessary. Finally, | |
524 | a single black pixel is added just above the lower left black box. | |
525 | """ | |
526 | ||
527 | #Draw outer black box | |
528 | for i in range(7): | |
529 | inv = -(i+1) | |
530 | for j in [0,6,-1,-7]: | |
531 | m[j][i] = 1 | |
532 | m[i][j] = 1 | |
533 | m[inv][j] = 1 | |
534 | m[j][inv] = 1 | |
535 | ||
536 | #Draw inner white box | |
537 | for i in range(1, 6): | |
538 | inv = -(i+1) | |
539 | for j in [1, 5, -2, -6]: | |
540 | m[j][i] = 0 | |
541 | m[i][j] = 0 | |
542 | m[inv][j] = 0 | |
543 | m[j][inv] = 0 | |
544 | ||
545 | #Draw inner black box | |
546 | for i in range(2, 5): | |
547 | for j in range(2, 5): | |
548 | inv = -(i+1) | |
549 | m[i][j] = 1 | |
550 | m[inv][j] = 1 | |
551 | m[j][inv] = 1 | |
552 | ||
553 | #Draw white border | |
554 | for i in range(8): | |
555 | inv = -(i+1) | |
556 | for j in [7, -8]: | |
557 | m[i][j] = 0 | |
558 | m[j][i] = 0 | |
559 | m[inv][j] = 0 | |
560 | m[j][inv] = 0 | |
561 | ||
562 | #To keep the code short, it draws an extra box | |
563 | #in the lower right corner, this removes it. | |
564 | for i in range(-8, 0): | |
565 | for j in range(-8, 0): | |
566 | m[i][j] = ' ' | |
567 | ||
568 | #Add the timing pattern | |
569 | bit = itertools.cycle([1,0]) | |
570 | for i in range(8, (len(m)-8)): | |
571 | b = next(bit) | |
572 | m[i][6] = b | |
573 | m[6][i] = b | |
574 | ||
575 | #Add the extra black pixel | |
576 | m[-8][8] = 1 | |
577 | ||
578 | def add_position_pattern(self, m): | |
579 | """This method draws the position adjustment patterns onto the QR | |
580 | Code. All QR code versions larger than one require these special boxes | |
581 | called position adjustment patterns. | |
582 | """ | |
583 | #Version 1 does not have a position adjustment pattern | |
584 | if self.version == 1: | |
585 | return | |
586 | ||
587 | #Get the coordinates for where to place the boxes | |
588 | coordinates = tables.position_adjustment[self.version] | |
589 | ||
590 | #Get the max and min coordinates to handle special cases | |
591 | min_coord = coordinates[0] | |
592 | max_coord = coordinates[-1] | |
593 | ||
594 | #Draw a box at each intersection of the coordinates | |
595 | for i in coordinates: | |
596 | for j in coordinates: | |
597 | #Do not draw these boxes because they would | |
598 | #interfere with the detection pattern | |
599 | if (i == min_coord and j == min_coord) or \ | |
600 | (i == min_coord and j == max_coord) or \ | |
601 | (i == max_coord and j == min_coord): | |
602 | continue | |
603 | ||
604 | #Center black pixel | |
605 | m[i][j] = 1 | |
606 | ||
607 | #Surround the pixel with a white box | |
608 | for x in [-1,1]: | |
609 | m[i+x][j+x] = 0 | |
610 | m[i+x][j] = 0 | |
611 | m[i][j+x] = 0 | |
612 | m[i-x][j+x] = 0 | |
613 | m[i+x][j-x] = 0 | |
614 | ||
615 | #Surround the white box with a black box | |
616 | for x in [-2,2]: | |
617 | for y in [0,-1,1]: | |
618 | m[i+x][j+x] = 1 | |
619 | m[i+x][j+y] = 1 | |
620 | m[i+y][j+x] = 1 | |
621 | m[i-x][j+x] = 1 | |
622 | m[i+x][j-x] = 1 | |
623 | ||
624 | def add_version_pattern(self, m): | |
625 | """For QR codes with a version 7 or higher, a special pattern | |
626 | specifying the code's version is required. | |
627 | ||
628 | For further information see: | |
629 | http://www.thonky.com/qr-code-tutorial/format-version-information/#example-of-version-7-information-string | |
630 | """ | |
631 | if self.version < 7: | |
632 | return | |
633 | ||
634 | #Get the bit fields for this code's version | |
635 | #We will iterate across the string, the bit string | |
636 | #needs the least significant digit in the zero-th position | |
637 | field = iter(tables.version_pattern[self.version][::-1]) | |
638 | ||
639 | #Where to start placing the pattern | |
640 | start = len(m)-11 | |
641 | ||
642 | #The version pattern is pretty odd looking | |
643 | for i in range(6): | |
644 | #The pattern is three modules wide | |
645 | for j in range(start, start+3): | |
646 | bit = int(next(field)) | |
647 | ||
648 | #Bottom Left | |
649 | m[i][j] = bit | |
650 | ||
651 | #Upper right | |
652 | m[j][i] = bit | |
653 | ||
654 | def make_masks(self, template): | |
655 | """This method generates all seven masks so that the best mask can | |
656 | be determined. The template parameter is a code matrix that will | |
657 | server as the base for all the generated masks. | |
658 | """ | |
659 | from copy import deepcopy | |
660 | ||
661 | nmasks = len(tables.mask_patterns) | |
662 | masks = [''] * nmasks | |
663 | count = 0 | |
664 | ||
665 | for n in range(nmasks): | |
666 | cur_mask = deepcopy(template) | |
667 | masks[n] = cur_mask | |
668 | ||
669 | #Add the type pattern bits to the code | |
670 | self.add_type_pattern(cur_mask, tables.type_bits[self.error][n]) | |
671 | ||
672 | #Get the mask pattern | |
673 | pattern = tables.mask_patterns[n] | |
674 | ||
675 | #This will read the 1's and 0's one at a time | |
676 | bits = iter(self.buffer.getvalue()) | |
677 | ||
678 | #These will help us do the up, down, up, down pattern | |
679 | row_start = itertools.cycle([len(cur_mask)-1, 0]) | |
680 | row_stop = itertools.cycle([-1,len(cur_mask)]) | |
681 | direction = itertools.cycle([-1, 1]) | |
682 | ||
683 | #The data pattern is added using pairs of columns | |
684 | for column in range(len(cur_mask)-1, 0, -2): | |
685 | ||
686 | #The vertical timing pattern is an exception to the rules, | |
687 | #move the column counter over by one | |
688 | if column <= 6: | |
689 | column = column - 1 | |
690 | ||
691 | #This will let us fill in the pattern | |
692 | #right-left, right-left, etc. | |
693 | column_pair = itertools.cycle([column, column-1]) | |
694 | ||
695 | #Go through each row in the pattern moving up, then down | |
696 | for row in range(next(row_start), next(row_stop), | |
697 | next(direction)): | |
698 | ||
699 | #Fill in the right then left column | |
700 | for i in range(2): | |
701 | col = next(column_pair) | |
702 | ||
703 | #Go to the next column if we encounter a | |
704 | #preexisting pattern (usually an alignment pattern) | |
705 | if cur_mask[row][col] != ' ': | |
706 | continue | |
707 | ||
708 | #Some versions don't have enough bits. You then fill | |
709 | #in the rest of the pattern with 0's. These are | |
710 | #called "remainder bits." | |
711 | try: | |
712 | bit = int(next(bits)) | |
713 | except: | |
714 | bit = 0 | |
715 | ||
716 | ||
717 | #If the pattern is True then flip the bit | |
718 | if pattern(row, col): | |
719 | cur_mask[row][col] = bit ^ 1 | |
720 | else: | |
721 | cur_mask[row][col] = bit | |
722 | ||
723 | #DEBUG CODE!!! | |
724 | #Save all of the masks as png files | |
725 | #for i, m in enumerate(masks): | |
726 | # _png(m, self.version, 'mask-{0}.png'.format(i), 5) | |
727 | ||
728 | return masks | |
729 | ||
730 | def choose_best_mask(self): | |
731 | """This method returns the index of the "best" mask as defined by | |
732 | having the lowest total penalty score. The penalty rules are defined | |
733 | by the standard. The mask with the lowest total score should be the | |
734 | easiest to read by optical scanners. | |
735 | """ | |
736 | self.scores = [] | |
737 | for n in range(len(self.masks)): | |
738 | self.scores.append([0,0,0,0]) | |
739 | ||
740 | #Score penalty rule number 1 | |
741 | #Look for five consecutive squares with the same color. | |
742 | #Each one found gets a penalty of 3 + 1 for every | |
743 | #same color square after the first five in the row. | |
744 | for (n, mask) in enumerate(self.masks): | |
745 | current = mask[0][0] | |
746 | counter = 0 | |
747 | total = 0 | |
748 | ||
749 | #Examine the mask row wise | |
750 | for row in range(0,len(mask)): | |
751 | counter = 0 | |
752 | for col in range(0,len(mask)): | |
753 | bit = mask[row][col] | |
754 | ||
755 | if bit == current: | |
756 | counter += 1 | |
757 | else: | |
758 | if counter >= 5: | |
759 | total += (counter - 5) + 3 | |
760 | counter = 1 | |
761 | current = bit | |
762 | if counter >= 5: | |
763 | total += (counter - 5) + 3 | |
764 | ||
765 | #Examine the mask column wise | |
766 | for col in range(0,len(mask)): | |
767 | counter = 0 | |
768 | for row in range(0,len(mask)): | |
769 | bit = mask[row][col] | |
770 | ||
771 | if bit == current: | |
772 | counter += 1 | |
773 | else: | |
774 | if counter >= 5: | |
775 | total += (counter - 5) + 3 | |
776 | counter = 1 | |
777 | current = bit | |
778 | if counter >= 5: | |
779 | total += (counter - 5) + 3 | |
780 | ||
781 | self.scores[n][0] = total | |
782 | ||
783 | #Score penalty rule 2 | |
784 | #This rule will add 3 to the score for each 2x2 block of the same | |
785 | #colored pixels there are. | |
786 | for (n, mask) in enumerate(self.masks): | |
787 | count = 0 | |
788 | #Don't examine the 0th and Nth row/column | |
789 | for i in range(0, len(mask)-1): | |
790 | for j in range(0, len(mask)-1): | |
791 | if mask[i][j] == mask[i+1][j] and \ | |
792 | mask[i][j] == mask[i][j+1] and \ | |
793 | mask[i][j] == mask[i+1][j+1]: | |
794 | count += 1 | |
795 | ||
796 | self.scores[n][1] = count * 3 | |
797 | ||
798 | #Score penalty rule 3 | |
799 | #This rule looks for 1011101 within the mask prefixed | |
800 | #and/or suffixed by four zeros. | |
801 | patterns = [[0,0,0,0,1,0,1,1,1,0,1], | |
802 | [1,0,1,1,1,0,1,0,0,0,0],] | |
803 | #[0,0,0,0,1,0,1,1,1,0,1,0,0,0,0]] | |
804 | ||
805 | for (n, mask) in enumerate(self.masks): | |
806 | nmatches = 0 | |
807 | ||
808 | for i in range(len(mask)): | |
809 | for j in range(len(mask)): | |
810 | for pattern in patterns: | |
811 | match = True | |
812 | k = j | |
813 | #Look for row matches | |
814 | for p in pattern: | |
815 | if k >= len(mask) or mask[i][k] != p: | |
816 | match = False | |
817 | break | |
818 | k += 1 | |
819 | if match: | |
820 | nmatches += 1 | |
821 | ||
822 | match = True | |
823 | k = j | |
824 | #Look for column matches | |
825 | for p in pattern: | |
826 | if k >= len(mask) or mask[k][i] != p: | |
827 | match = False | |
828 | break | |
829 | k += 1 | |
830 | if match: | |
831 | nmatches += 1 | |
832 | ||
833 | ||
834 | self.scores[n][2] = nmatches * 40 | |
835 | ||
836 | #Score the last rule, penalty rule 4. This rule measures how close | |
837 | #the pattern is to being 50% black. The further it deviates from | |
838 | #this this ideal the higher the penalty. | |
839 | for (n, mask) in enumerate(self.masks): | |
840 | nblack = 0 | |
841 | for row in mask: | |
842 | nblack += sum(row) | |
843 | ||
844 | total_pixels = len(mask)**2 | |
845 | ratio = nblack / total_pixels | |
846 | percent = (ratio * 100) - 50 | |
847 | self.scores[n][3] = int((abs(int(percent)) / 5) * 10) | |
848 | ||
849 | ||
850 | #Calculate the total for each score | |
851 | totals = [0] * len(self.scores) | |
852 | for i in range(len(self.scores)): | |
853 | for j in range(len(self.scores[i])): | |
854 | totals[i] += self.scores[i][j] | |
855 | ||
856 | #DEBUG CODE!!! | |
857 | #Prints out a table of scores | |
858 | #print('Rule Scores\n 1 2 3 4 Total') | |
859 | #for i in range(len(self.scores)): | |
860 | # print(i, end='') | |
861 | # for s in self.scores[i]: | |
862 | # print('{0: >6}'.format(s), end='') | |
863 | # print('{0: >7}'.format(totals[i])) | |
864 | #print('Mask Chosen: {0}'.format(totals.index(min(totals)))) | |
865 | ||
866 | #The lowest total wins | |
867 | return totals.index(min(totals)) | |
868 | ||
869 | def add_type_pattern(self, m, type_bits): | |
870 | """This will add the pattern to the QR code that represents the error | |
871 | level and the type of mask used to make the code. | |
872 | """ | |
873 | field = iter(type_bits) | |
874 | for i in range(7): | |
875 | bit = int(next(field)) | |
876 | ||
877 | #Skip the timing bits | |
878 | if i < 6: | |
879 | m[8][i] = bit | |
880 | else: | |
881 | m[8][i+1] = bit | |
882 | ||
883 | if -8 < -(i+1): | |
884 | m[-(i+1)][8] = bit | |
885 | ||
886 | for i in range(-8,0): | |
887 | bit = int(next(field)) | |
888 | ||
889 | m[8][i] = bit | |
890 | ||
891 | i = -i | |
892 | #Skip timing column | |
893 | if i > 6: | |
894 | m[i][8] = bit | |
895 | else: | |
896 | m[i-1][8] = bit | |
897 | ||
898 | ############################################################################## | |
899 | ############################################################################## | |
900 | # | |
901 | # Output Functions | |
902 | # | |
903 | ############################################################################## | |
904 | ############################################################################## | |
905 | ||
906 | def _get_writable(stream_or_path, mode): | |
907 | """This method returns a tuple containing the stream and a flag to indicate | |
908 | if the stream should be automatically closed. | |
909 | ||
910 | The `stream_or_path` parameter is returned if it is an open writable stream. | |
911 | Otherwise, it treats the `stream_or_path` parameter as a file path and | |
912 | opens it with the given mode. | |
913 | ||
914 | It is used by the svg and png methods to interpret the file parameter. | |
915 | ||
916 | :type stream_or_path: str | io.BufferedIOBase | |
917 | :type mode: str | unicode | |
918 | :rtype: (io.BufferedIOBase, bool) | |
919 | """ | |
920 | is_stream = hasattr(stream_or_path, 'write') | |
921 | if not is_stream: | |
922 | # No stream provided, treat "stream_or_path" as path | |
923 | stream_or_path = open(stream_or_path, mode) | |
924 | return stream_or_path, not is_stream | |
925 | ||
926 | ||
927 | def _get_png_size(version, scale, quiet_zone=4): | |
928 | """See: QRCode.get_png_size | |
929 | ||
930 | This function was abstracted away from QRCode to allow for the output of | |
931 | QR codes during the build process, i.e. for debugging. It works | |
932 | just the same except you must specify the code's version. This is needed | |
933 | to calculate the PNG's size. | |
934 | """ | |
935 | #Formula: scale times number of modules plus the border on each side | |
936 | return (int(scale) * tables.version_size[version]) + (2 * quiet_zone * int(scale)) | |
937 | ||
938 | ||
939 | def _terminal(code, module_color='default', background='reverse', quiet_zone=4): | |
940 | """This method returns a string containing ASCII escape codes, | |
941 | such that if printed to a terminal, it will display a vaild | |
942 | QR code. The module_color and the background color should be keys | |
943 | in the tables.term_colors table for printing using the 8/16 | |
944 | color scheme. Alternatively, they can be a number between 0 and | |
945 | 256 in order to use the 88/256 color scheme. Otherwise, a | |
946 | ValueError will be raised. | |
947 | ||
948 | Note, the code is outputted by changing the background color. Then | |
949 | two spaces are written to the terminal. Finally, the terminal is | |
950 | reset back to how it was. | |
951 | """ | |
952 | buf = io.StringIO() | |
953 | ||
954 | def draw_border(): | |
955 | for i in range(quiet_zone): | |
956 | buf.write(background) | |
957 | ||
958 | if module_color in tables.term_colors: | |
959 | data = '\033[{0}m \033[0m'.format( | |
960 | tables.term_colors[module_color]) | |
961 | elif 0 <= module_color <= 256: | |
962 | data = '\033[48;5;{0}m \033[0m'.format(module_color) | |
963 | else: | |
964 | raise ValueError('The module color, {0}, must a key in ' | |
965 | 'pyqrcode.tables.term_colors or a number ' | |
966 | 'between 0 and 256.'.format( | |
967 | module_color)) | |
968 | ||
969 | if background in tables.term_colors: | |
970 | background = '\033[{0}m \033[0m'.format( | |
971 | tables.term_colors[background]) | |
972 | elif 0 <= background <= 256: | |
973 | background = '\033[48;5;{0}m \033[0m'.format(background) | |
974 | else: | |
975 | raise ValueError('The background color, {0}, must a key in ' | |
976 | 'pyqrcode.tables.term_colors or a number ' | |
977 | 'between 0 and 256.'.format( | |
978 | background)) | |
979 | ||
980 | #This will be the beginning and ending row for the code. | |
981 | border_row = background * (len(code[0]) + (2 * quiet_zone)) | |
982 | ||
983 | #Make sure we begin on a new line, and force the terminal back | |
984 | #to normal | |
985 | buf.write('\n') | |
986 | ||
987 | #QRCodes have a quiet zone consisting of background modules | |
988 | for i in range(quiet_zone): | |
989 | buf.write(border_row) | |
990 | buf.write('\n') | |
991 | ||
992 | for row in code: | |
993 | #Each code has a quiet zone on the left side, this is the left | |
994 | #border for this code | |
995 | draw_border() | |
996 | ||
997 | for bit in row: | |
998 | if bit == 1: | |
999 | buf.write(data) | |
1000 | elif bit == 0: | |
1001 | buf.write(background) | |
1002 | ||
1003 | #Each row ends with a quiet zone on the right side, this is the | |
1004 | #right hand border background modules | |
1005 | draw_border() | |
1006 | buf.write('\n') | |
1007 | ||
1008 | #QRCodes have a background quiet zone row following the code | |
1009 | for i in range(quiet_zone): | |
1010 | buf.write(border_row) | |
1011 | buf.write('\n') | |
1012 | ||
1013 | return buf.getvalue() | |
1014 | ||
1015 | def _text(code, quiet_zone=4): | |
1016 | """This method returns a text based representation of the QR code. | |
1017 | This is useful for debugging purposes. | |
1018 | """ | |
1019 | buf = io.StringIO() | |
1020 | ||
1021 | border_row = '0' * (len(code[0]) + (quiet_zone*2)) | |
1022 | ||
1023 | #Every QR code start with a quiet zone at the top | |
1024 | for b in range(quiet_zone): | |
1025 | buf.write(border_row) | |
1026 | buf.write('\n') | |
1027 | ||
1028 | for row in code: | |
1029 | #Draw the starting quiet zone | |
1030 | for b in range(quiet_zone): | |
1031 | buf.write('0') | |
1032 | ||
1033 | #Actually draw the QR code | |
1034 | for bit in row: | |
1035 | if bit == 1: | |
1036 | buf.write('1') | |
1037 | elif bit == 0: | |
1038 | buf.write('0') | |
1039 | #This is for debugging unfinished QR codes, | |
1040 | #unset pixels will be spaces. | |
1041 | else: | |
1042 | buf.write(' ') | |
1043 | ||
1044 | #Draw the ending quiet zone | |
1045 | for b in range(quiet_zone): | |
1046 | buf.write('0') | |
1047 | buf.write('\n') | |
1048 | ||
1049 | #Every QR code ends with a quiet zone at the bottom | |
1050 | for b in range(quiet_zone): | |
1051 | buf.write(border_row) | |
1052 | buf.write('\n') | |
1053 | ||
1054 | return buf.getvalue() | |
1055 | ||
1056 | def _xbm(code, scale=1, quiet_zone=4): | |
1057 | """This function will format the QR code as a X BitMap. | |
1058 | This can be used to display the QR code with Tkinter. | |
1059 | """ | |
1060 | try: | |
1061 | str = unicode # Python 2 | |
1062 | except NameError: | |
1063 | str = __builtins__['str'] | |
1064 | ||
1065 | buf = io.StringIO() | |
1066 | ||
1067 | # Calculate the width in pixels | |
1068 | pixel_width = (len(code[0]) + quiet_zone * 2) * scale | |
1069 | ||
1070 | # Add the size information and open the pixel data section | |
1071 | buf.write('#define im_width ') | |
1072 | buf.write(str(pixel_width)) | |
1073 | buf.write('\n') | |
1074 | buf.write('#define im_height ') | |
1075 | buf.write(str(pixel_width)) | |
1076 | buf.write('\n') | |
1077 | buf.write('static char im_bits[] = {\n') | |
1078 | ||
1079 | # Calculate the number of bytes per row | |
1080 | byte_width = int(math.ceil(pixel_width / 8.0)) | |
1081 | ||
1082 | # Add the top quiet zone | |
1083 | buf.write(('0x00,' * byte_width + '\n') * quiet_zone * scale) | |
1084 | for row in code: | |
1085 | # Add the left quiet zone | |
1086 | row_bits = '0' * quiet_zone * scale | |
1087 | # Add the actual QR code | |
1088 | for pixel in row: | |
1089 | row_bits += str(pixel) * scale | |
1090 | # Add the right quiet zone | |
1091 | row_bits += '0' * quiet_zone * scale | |
1092 | # Format the row | |
1093 | formated_row = '' | |
1094 | for b in range(byte_width): | |
1095 | formated_row += '0x{0:02x},'.format(int(row_bits[:8][::-1], 2)) | |
1096 | row_bits = row_bits[8:] | |
1097 | formated_row += '\n' | |
1098 | # Add the formatted row | |
1099 | buf.write(formated_row * scale) | |
1100 | # Add the bottom quiet zone and close the pixel data section | |
1101 | buf.write(('0x00,' * byte_width + '\n') * quiet_zone * scale) | |
1102 | buf.write('};') | |
1103 | ||
1104 | return buf.getvalue() | |
1105 | ||
1106 | def _svg(code, version, file, scale=1, module_color='#000', background=None, | |
1107 | quiet_zone=4, xmldecl=True, svgns=True, title=None, svgclass='pyqrcode', | |
1108 | lineclass='pyqrline', omithw=False, debug=False): | |
1109 | """This function writes the QR code out as an SVG document. The | |
1110 | code is drawn by drawing only the modules corresponding to a 1. They | |
1111 | are drawn using a line, such that contiguous modules in a row | |
1112 | are drawn with a single line. The file parameter is used to | |
1113 | specify where to write the document to. It can either be a writable (binary) | |
1114 | stream or a file path. The scale parameter is sets how large to draw | |
1115 | a single module. By default one pixel is used to draw a single | |
1116 | module. This may make the code to small to be read efficiently. | |
1117 | Increasing the scale will make the code larger. This method will accept | |
1118 | fractional scales (e.g. 2.5). | |
1119 | ||
1120 | :param module_color: Color of the QR code (default: ``#000`` (black)) | |
1121 | :param background: Optional background color. | |
1122 | (default: ``None`` (no background)) | |
1123 | :param quiet_zone: Border around the QR code (also known as quiet zone) | |
1124 | (default: ``4``). Set to zero (``0``) if the code shouldn't | |
1125 | have a border. | |
1126 | :param xmldecl: Inidcates if the XML declaration header should be written | |
1127 | (default: ``True``) | |
1128 | :param svgns: Indicates if the SVG namespace should be written | |
1129 | (default: ``True``) | |
1130 | :param title: Optional title of the generated SVG document. | |
1131 | :param svgclass: The CSS class of the SVG document | |
1132 | (if set to ``None``, the SVG element won't have a class). | |
1133 | :param lineclass: The CSS class of the path element | |
1134 | (if set to ``None``, the path won't have a class). | |
1135 | :param omithw: Indicates if width and height attributes should be | |
1136 | omitted (default: ``False``). If these attributes are omitted, | |
1137 | a ``viewBox`` attribute will be added to the document. | |
1138 | :param debug: Inidicates if errors in the QR code should be added to the | |
1139 | output (default: ``False``). | |
1140 | """ | |
1141 | from functools import partial | |
1142 | from xml.sax.saxutils import quoteattr | |
1143 | ||
1144 | def write_unicode(write_meth, unicode_str): | |
1145 | """\ | |
1146 | Encodes the provided string into UTF-8 and writes the result using | |
1147 | the `write_meth`. | |
1148 | """ | |
1149 | write_meth(unicode_str.encode('utf-8')) | |
1150 | ||
1151 | def line(x, y, length, relative): | |
1152 | """Returns coordinates to draw a line with the provided length. | |
1153 | """ | |
1154 | return '{0}{1} {2}h{3}'.format(('m' if relative else 'M'), x, y, length) | |
1155 | ||
1156 | def errline(col_number, row_number): | |
1157 | """Returns the coordinates to draw an error bit. | |
1158 | """ | |
1159 | # Debug path uses always absolute coordinates | |
1160 | # .5 == stroke / 2 | |
1161 | return line(col_number + quiet_zone, row_number + quiet_zone + .5, 1, False) | |
1162 | ||
1163 | f, autoclose = _get_writable(file, 'wb') | |
1164 | write = partial(write_unicode, f.write) | |
1165 | write_bytes = f.write | |
1166 | # Write the document header | |
1167 | if xmldecl: | |
1168 | write_bytes(b'<?xml version="1.0" encoding="UTF-8"?>\n') | |
1169 | write_bytes(b'<svg') | |
1170 | if svgns: | |
1171 | write_bytes(b' xmlns="http://www.w3.org/2000/svg"') | |
1172 | size = tables.version_size[version] * scale + (2 * quiet_zone * scale) | |
1173 | if not omithw: | |
1174 | write(' height="{0}" width="{0}"'.format(size)) | |
1175 | else: | |
1176 | write(' viewBox="0 0 {0} {0}"'.format(size)) | |
1177 | if svgclass is not None: | |
1178 | write_bytes(b' class=') | |
1179 | write(quoteattr(svgclass)) | |
1180 | write_bytes(b'>') | |
1181 | if title is not None: | |
1182 | write('<title>{0}</title>'.format(title)) | |
1183 | ||
1184 | # Draw a background rectangle if necessary | |
1185 | if background is not None: | |
1186 | write('<path fill="{1}" d="M0 0h{0}v{0}h-{0}z"/>' | |
1187 | .format(size, background)) | |
1188 | write_bytes(b'<path') | |
1189 | if scale != 1: | |
1190 | write(' transform="scale({0})"'.format(scale)) | |
1191 | if module_color is not None: | |
1192 | write_bytes(b' stroke=') | |
1193 | write(quoteattr(module_color)) | |
1194 | if lineclass is not None: | |
1195 | write_bytes(b' class=') | |
1196 | write(quoteattr(lineclass)) | |
1197 | write_bytes(b' d="') | |
1198 | # Used to keep track of unknown/error coordinates. | |
1199 | debug_path = '' | |
1200 | # Current pen pointer position | |
1201 | x, y = -quiet_zone, quiet_zone - .5 # .5 == stroke-width / 2 | |
1202 | wrote_bit = False | |
1203 | # Loop through each row of the code | |
1204 | for rnumber, row in enumerate(code): | |
1205 | start_column = 0 # Reset the starting column number | |
1206 | coord = '' # Reset row coordinates | |
1207 | y += 1 # Pen position on y-axis | |
1208 | length = 0 # Reset line length | |
1209 | # Examine every bit in the row | |
1210 | for colnumber, bit in enumerate(row): | |
1211 | if bit == 1: | |
1212 | length += 1 | |
1213 | else: | |
1214 | if length: | |
1215 | x = start_column - x | |
1216 | coord += line(x, y, length, relative=wrote_bit) | |
1217 | x = start_column + length | |
1218 | y = 0 # y-axis won't change unless the row changes | |
1219 | length = 0 | |
1220 | wrote_bit = True | |
1221 | start_column = colnumber + 1 | |
1222 | if debug and bit != 0: | |
1223 | debug_path += errline(colnumber, rnumber) | |
1224 | if length: | |
1225 | x = start_column - x | |
1226 | coord += line(x, y, length, relative=wrote_bit) | |
1227 | x = start_column + length | |
1228 | wrote_bit = True | |
1229 | write(coord) | |
1230 | # Close path | |
1231 | write_bytes(b'"/>') | |
1232 | if debug and debug_path: | |
1233 | write_bytes(b'<path') | |
1234 | if scale != 1: | |
1235 | write(' transform="scale({0})"'.format(scale)) | |
1236 | write(' class="pyqrerr" stroke="red" d="{0}"/>'.format(debug_path)) | |
1237 | # Close document | |
1238 | write_bytes(b'</svg>\n') | |
1239 | if autoclose: | |
1240 | f.close() | |
1241 | ||
1242 | ||
1243 | def _png(code, version, file, scale=1, module_color=(0, 0, 0, 255), | |
1244 | background=(255, 255, 255, 255), quiet_zone=4, debug=False): | |
1245 | """See: pyqrcode.QRCode.png() | |
1246 | ||
1247 | This function was abstracted away from QRCode to allow for the output of | |
1248 | QR codes during the build process, i.e. for debugging. It works | |
1249 | just the same except you must specify the code's version. This is needed | |
1250 | to calculate the PNG's size. | |
1251 | ||
1252 | This method will write the given file out as a PNG file. Note, it | |
1253 | depends on the PyPNG module to do this. | |
1254 | ||
1255 | :param module_color: Color of the QR code (default: ``(0, 0, 0, 255)`` (black)) | |
1256 | :param background: Optional background color. If set to ``None`` the PNG | |
1257 | will have a transparent background. | |
1258 | (default: ``(255, 255, 255, 255)`` (white)) | |
1259 | :param quiet_zone: Border around the QR code (also known as quiet zone) | |
1260 | (default: ``4``). Set to zero (``0``) if the code shouldn't | |
1261 | have a border. | |
1262 | :param debug: Inidicates if errors in the QR code should be added (as red | |
1263 | modules) to the output (default: ``False``). | |
1264 | """ | |
1265 | import png | |
1266 | ||
1267 | # Coerce scale parameter into an integer | |
1268 | try: | |
1269 | scale = int(scale) | |
1270 | except ValueError: | |
1271 | raise ValueError('The scale parameter must be an integer') | |
1272 | ||
1273 | def scale_code(size): | |
1274 | """To perform the scaling we need to inflate the number of bits. | |
1275 | The PNG library expects all of the bits when it draws the PNG. | |
1276 | Effectively, we double, tripple, etc. the number of columns and | |
1277 | the number of rows. | |
1278 | """ | |
1279 | # This is one row's worth of each possible module | |
1280 | # PNG's use 0 for black and 1 for white, this is the | |
1281 | # reverse of the QR standard | |
1282 | black = [0] * scale | |
1283 | white = [1] * scale | |
1284 | ||
1285 | # Tuple to lookup colors | |
1286 | # The 3rd color is the module_color unless "debug" is enabled | |
1287 | colors = (white, black, (([2] * scale) if debug else black)) | |
1288 | ||
1289 | # Whitespace added on the left and right side | |
1290 | border_module = white * quiet_zone | |
1291 | # This is the row to show up at the top and bottom border | |
1292 | border_row = [[1] * size] * scale * quiet_zone | |
1293 | ||
1294 | # This will hold the final PNG's bits | |
1295 | bits = [] | |
1296 | ||
1297 | # Add scale rows before the code as a border, | |
1298 | # as per the standard | |
1299 | bits.extend(border_row) | |
1300 | ||
1301 | # Add each row of the to the final PNG bits | |
1302 | for row in code: | |
1303 | tmp_row = [] | |
1304 | ||
1305 | # Add one all white module to the beginning | |
1306 | # to create the vertical border | |
1307 | tmp_row.extend(border_module) | |
1308 | ||
1309 | # Go through each bit in the code | |
1310 | for bit in row: | |
1311 | # Use the standard color or the "debug" color | |
1312 | tmp_row.extend(colors[(bit if bit in (0, 1) else 2)]) | |
1313 | ||
1314 | # Add one all white module to the end | |
1315 | # to create the vertical border | |
1316 | tmp_row.extend(border_module) | |
1317 | ||
1318 | # Copy each row scale times | |
1319 | for n in range(scale): | |
1320 | bits.append(tmp_row) | |
1321 | ||
1322 | # Add the bottom border | |
1323 | bits.extend(border_row) | |
1324 | ||
1325 | return bits | |
1326 | ||
1327 | def png_pallete_color(color): | |
1328 | """This creates a palette color from a list or tuple. The list or | |
1329 | tuple must be of length 3 (for rgb) or 4 (for rgba). The values | |
1330 | must be between 0 and 255. Note rgb colors will be given an added | |
1331 | alpha component set to 255. | |
1332 | ||
1333 | The pallete color is represented as a list, this is what is returned. | |
1334 | """ | |
1335 | if color is None: | |
1336 | return () | |
1337 | if not isinstance(color, (tuple, list)): | |
1338 | r, g, b = _hex_to_rgb(color) | |
1339 | return r, g, b, 255 | |
1340 | rgba = [] | |
1341 | if not (3 <= len(color) <= 4): | |
1342 | raise ValueError('Colors must be a list or tuple of length ' | |
1343 | ' 3 or 4. You passed in "{0}".'.format(color)) | |
1344 | for c in color: | |
1345 | c = int(c) | |
1346 | if 0 <= c <= 255: | |
1347 | rgba.append(int(c)) | |
1348 | else: | |
1349 | raise ValueError('Color components must be between 0 and 255') | |
1350 | # Make all colors have an alpha channel | |
1351 | if len(rgba) == 3: | |
1352 | rgba.append(255) | |
1353 | return tuple(rgba) | |
1354 | ||
1355 | if module_color is None: | |
1356 | raise ValueError('The module_color must not be None') | |
1357 | ||
1358 | bitdepth = 1 | |
1359 | # foreground aka module color | |
1360 | fg_col = png_pallete_color(module_color) | |
1361 | transparent = background is None | |
1362 | # If background color is set to None, the inverse color of the | |
1363 | # foreground color is calculated | |
1364 | bg_col = png_pallete_color(background) if background is not None else tuple([255 - c for c in fg_col]) | |
1365 | # Assume greyscale if module color is black and background color is white | |
1366 | greyscale = fg_col[:3] == (0, 0, 0) and (not debug and transparent or bg_col == (255, 255, 255, 255)) | |
1367 | transparent_color = 1 if transparent and greyscale else None | |
1368 | palette = [fg_col, bg_col] if not greyscale else None | |
1369 | if debug: | |
1370 | # Add "red" as color for error modules | |
1371 | palette.append((255, 0, 0, 255)) | |
1372 | bitdepth = 2 | |
1373 | ||
1374 | # The size of the PNG | |
1375 | size = _get_png_size(version, scale, quiet_zone) | |
1376 | ||
1377 | # We need to increase the size of the code to match up to the | |
1378 | # scale parameter. | |
1379 | code_rows = scale_code(size) | |
1380 | ||
1381 | # Write out the PNG | |
1382 | f, autoclose = _get_writable(file, 'wb') | |
1383 | w = png.Writer(width=size, height=size, greyscale=greyscale, | |
1384 | transparent=transparent_color, palette=palette, | |
1385 | bitdepth=bitdepth) | |
1386 | try: | |
1387 | w.write(f, code_rows) | |
1388 | finally: | |
1389 | if autoclose: | |
1390 | f.close() | |
1391 | ||
1392 | ||
1393 | def _eps(code, version, file_or_path, scale=1, module_color=(0, 0, 0), | |
1394 | background=None, quiet_zone=4): | |
1395 | """This function writes the QR code out as an EPS document. The | |
1396 | code is drawn by drawing only the modules corresponding to a 1. They | |
1397 | are drawn using a line, such that contiguous modules in a row | |
1398 | are drawn with a single line. The file parameter is used to | |
1399 | specify where to write the document to. It can either be a writable (text) | |
1400 | stream or a file path. The scale parameter is sets how large to draw | |
1401 | a single module. By default one point (1/72 inch) is used to draw a single | |
1402 | module. This may make the code to small to be read efficiently. | |
1403 | Increasing the scale will make the code larger. This function will accept | |
1404 | fractional scales (e.g. 2.5). | |
1405 | ||
1406 | :param module_color: Color of the QR code (default: ``(0, 0, 0)`` (black)) | |
1407 | The color can be specified as triple of floats (range: 0 .. 1) or | |
1408 | triple of integers (range: 0 .. 255) or as hexadecimal value (i.e. | |
1409 | ``#36c`` or ``#33B200``). | |
1410 | :param background: Optional background color. | |
1411 | (default: ``None`` (no background)). See `module_color` for the | |
1412 | supported values. | |
1413 | :param quiet_zone: Border around the QR code (also known as quiet zone) | |
1414 | (default: ``4``). Set to zero (``0``) if the code shouldn't | |
1415 | have a border. | |
1416 | """ | |
1417 | from functools import partial | |
1418 | import time | |
1419 | import textwrap | |
1420 | ||
1421 | def write_line(writemeth, content): | |
1422 | """\ | |
1423 | Writes `content` and ``LF``. | |
1424 | """ | |
1425 | # Postscript: Max. 255 characters per line | |
1426 | for line in textwrap.wrap(content, 255): | |
1427 | writemeth(line) | |
1428 | writemeth('\n') | |
1429 | ||
1430 | def line(offset, length): | |
1431 | """\ | |
1432 | Returns coordinates to draw a line with the provided length. | |
1433 | """ | |
1434 | res = '' | |
1435 | if offset > 0: | |
1436 | res = ' {0} 0 m'.format(offset) | |
1437 | res += ' {0} 0 l'.format(length) | |
1438 | return res | |
1439 | ||
1440 | def rgb_to_floats(color): | |
1441 | """\ | |
1442 | Converts the provided color into an acceptable format for Postscript's | |
1443 | ``setrgbcolor`` | |
1444 | """ | |
1445 | def to_float(clr): | |
1446 | if isinstance(clr, float): | |
1447 | if not 0.0 <= clr <= 1.0: | |
1448 | raise ValueError('Invalid color "{0}". Not in range 0 .. 1' | |
1449 | .format(clr)) | |
1450 | return clr | |
1451 | if not 0 <= clr <= 255: | |
1452 | raise ValueError('Invalid color "{0}". Not in range 0 .. 255' | |
1453 | .format(clr)) | |
1454 | return 1/255.0 * clr if clr != 1 else clr | |
1455 | ||
1456 | if not isinstance(color, (tuple, list)): | |
1457 | color = _hex_to_rgb(color) | |
1458 | return tuple([to_float(i) for i in color]) | |
1459 | ||
1460 | f, autoclose = _get_writable(file_or_path, 'w') | |
1461 | writeline = partial(write_line, f.write) | |
1462 | size = tables.version_size[version] * scale + (2 * quiet_zone * scale) | |
1463 | # Write common header | |
1464 | writeline('%!PS-Adobe-3.0 EPSF-3.0') | |
1465 | writeline('%%Creator: PyQRCode <https://pypi.python.org/pypi/PyQRCode/>') | |
1466 | writeline('%%CreationDate: {0}'.format(time.strftime("%Y-%m-%d %H:%M:%S"))) | |
1467 | writeline('%%DocumentData: Clean7Bit') | |
1468 | writeline('%%BoundingBox: 0 0 {0} {0}'.format(size)) | |
1469 | # Write the shortcuts | |
1470 | writeline('/M { moveto } bind def') | |
1471 | writeline('/m { rmoveto } bind def') | |
1472 | writeline('/l { rlineto } bind def') | |
1473 | mod_color = module_color if module_color == (0, 0, 0) else rgb_to_floats(module_color) | |
1474 | if background is not None: | |
1475 | writeline('{0:f} {1:f} {2:f} setrgbcolor clippath fill' | |
1476 | .format(*rgb_to_floats(background))) | |
1477 | if mod_color == (0, 0, 0): | |
1478 | # Reset RGB color back to black iff module color is black | |
1479 | # In case module color != black set the module RGB color later | |
1480 | writeline('0 0 0 setrgbcolor') | |
1481 | if mod_color != (0, 0, 0): | |
1482 | writeline('{0:f} {1:f} {2:f} setrgbcolor'.format(*mod_color)) | |
1483 | if scale != 1: | |
1484 | writeline('{0} {0} scale'.format(scale)) | |
1485 | writeline('newpath') | |
1486 | # Current pen position y-axis | |
1487 | # Note: 0, 0 = lower left corner in PS coordinate system | |
1488 | y = tables.version_size[version] + quiet_zone + .5 # .5 = linewidth / 2 | |
1489 | last_bit = 1 | |
1490 | # Loop through each row of the code | |
1491 | for row in code: | |
1492 | offset = 0 # Set x-offset of the pen | |
1493 | length = 0 | |
1494 | y -= 1 # Move pen along y-axis | |
1495 | coord = '{0} {1} M'.format(quiet_zone, y) # Move pen to initial pos | |
1496 | for bit in row: | |
1497 | if bit != last_bit: | |
1498 | if length: | |
1499 | coord += line(offset, length) | |
1500 | offset = 0 | |
1501 | length = 0 | |
1502 | last_bit = bit | |
1503 | if bit == 1: | |
1504 | length += 1 | |
1505 | else: | |
1506 | offset += 1 | |
1507 | if length: | |
1508 | coord += line(offset, length) | |
1509 | writeline(coord) | |
1510 | writeline('stroke') | |
1511 | writeline('%%EOF') | |
1512 | if autoclose: | |
1513 | f.close() | |
1514 | ||
1515 | ||
1516 | def _hex_to_rgb(color): | |
1517 | """\ | |
1518 | Helper function to convert a color provided in hexadecimal format | |
1519 | as RGB triple. | |
1520 | """ | |
1521 | if color[0] == '#': | |
1522 | color = color[1:] | |
1523 | if len(color) == 3: | |
1524 | color = color[0] * 2 + color[1] * 2 + color[2] * 2 | |
1525 | if len(color) != 6: | |
1526 | raise ValueError('Input #{0} is not in #RRGGBB format'.format(color)) | |
1527 | return [int(n, 16) for n in (color[:2], color[2:4], color[4:])] |
0 | # -*- coding: utf-8 -*- | |
1 | # Copyright (c) 2013, Michael Nooner | |
2 | # All rights reserved. | |
3 | # | |
4 | # Redistribution and use in source and binary forms, with or without | |
5 | # modification, are permitted provided that the following conditions are met: | |
6 | # * Redistributions of source code must retain the above copyright | |
7 | # notice, this list of conditions and the following disclaimer. | |
8 | # * Redistributions in binary form must reproduce the above copyright | |
9 | # notice, this list of conditions and the following disclaimer in the | |
10 | # documentation and/or other materials provided with the distribution. | |
11 | # * Neither the name of the copyright holder nor the names of its | |
12 | # contributors may be used to endorse or promote products derived from | |
13 | # this software without specific prior written permission | |
14 | # | |
15 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
16 | # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 | # ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY | |
19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
24 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | """This module lists out all of the tables needed to create a QR code. | |
26 | If you are viewing this in the HTML documentation, I recommend reading the | |
27 | actual file instead. The formating for the tables is much more readable. | |
28 | """ | |
29 | from __future__ import division, unicode_literals | |
30 | ||
31 | #: This defines the QR Code's 'mode' which sets what | |
32 | #: type of code it is along with its size. | |
33 | modes = { | |
34 | 'numeric': 1, | |
35 | 'alphanumeric': 2, | |
36 | 'binary': 4, | |
37 | 'kanji': 8, | |
38 | } | |
39 | ||
40 | #: This defines the amount of error correction. The dictionary | |
41 | #: allows the user to specify this in several ways. | |
42 | error_level = {'L': 'L', 'l': 'L', '7%': 'L', .7: 'L', | |
43 | 'M': 'M', 'm': 'M', '15%': 'M', .15: 'M', | |
44 | 'Q': 'Q', 'q': 'Q', '25%': 'Q', .25: 'Q', | |
45 | 'H': 'H', 'h': 'H', '30%': 'H', .30: 'H'} | |
46 | ||
47 | #: This is a dictionary holds how long the "data length" field is for | |
48 | #: each version and mode of the QR Code. | |
49 | data_length_field = {9: {1: 10, 2: 9, 4: 8, 8: 8}, | |
50 | 26: {1: 12, 2: 11, 4: 16, 8: 10}, | |
51 | 40: {1: 14, 2: 13, 4: 16, 8: 12}} | |
52 | ||
53 | #: QR Codes uses a unique ASCII-like table for the 'alphanumeric' mode. | |
54 | #: This is a dictionary representing that unique table, where the | |
55 | #: keys are the possible characters in the data and the values | |
56 | #: are the character's numeric representation. | |
57 | ascii_codes = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, | |
58 | '8': 8, '9': 9, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, | |
59 | 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19, 'K': 20, 'L': 21, | |
60 | 'M': 22, 'N': 23, 'O': 24, 'P': 25, 'Q': 26, 'R': 27, 'S': 28, | |
61 | 'T': 29, 'U': 30, 'V': 31, 'W': 32, 'X': 33, 'Y': 34, 'Z': 35, | |
62 | ' ': 36, '$': 37, '%': 38, '*': 39, '+': 40, '-': 41, '.': 42, | |
63 | '/': 43, ':': 44} | |
64 | ||
65 | #: This array specifies the size of a QR Code in pixels. These numbers are | |
66 | #: defined in the standard. The indexes correspond to the QR Code's | |
67 | #: version number. This array was taken from: | |
68 | #: | |
69 | #: http://www.denso-wave.com/qrcode/vertable1-e.html | |
70 | version_size = [None, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, | |
71 | 61, 65, 69, 73, 77, 81, 85, 89, 93, 97, | |
72 | 101, 105, 109, 113, 117, 121, 125, 129, 133, 137, | |
73 | 141, 145, 149, 153, 157, 161, 165, 169, 173, 177] | |
74 | ||
75 | #: This dictionary lists the data capacity for all possible QR Codes. | |
76 | #: This dictionary is organized where the first key corresponds to the | |
77 | #: QR Code version number. The next key corresponds to the error | |
78 | #: correction level, see error. The final key corresponds to | |
79 | #: the mode number, see modes. The zero mode number represents the | |
80 | #: possible "data bits." This table was taken from: | |
81 | #: | |
82 | #: http://www.denso-wave.com/qrcode/vertable1-e.html | |
83 | data_capacity = { | |
84 | 1: { | |
85 | "L": {0: 152, 1: 41, 2: 25, 4: 17, 8: 10, }, | |
86 | "M": {0: 128, 1: 34, 2: 20, 4: 14, 8: 8, }, | |
87 | "Q": {0: 104, 1: 27, 2: 16, 4: 11, 8: 7, }, | |
88 | "H": {0: 72, 1: 17, 2: 10, 4: 7, 8: 4, }}, | |
89 | 2: { | |
90 | "L": {0: 272, 1: 77, 2: 47, 4: 32, 8: 20, }, | |
91 | "M": {0: 224, 1: 63, 2: 38, 4: 26, 8: 16, }, | |
92 | "Q": {0: 176, 1: 48, 2: 29, 4: 20, 8: 12, }, | |
93 | "H": {0: 128, 1: 34, 2: 20, 4: 14, 8: 8, }}, | |
94 | 3: { | |
95 | "L": {0: 440, 1: 127, 2: 77, 4: 53, 8: 32, }, | |
96 | "M": {0: 352, 1: 101, 2: 61, 4: 42, 8: 26, }, | |
97 | "Q": {0: 272, 1: 77, 2: 47, 4: 32, 8: 20, }, | |
98 | "H": {0: 208, 1: 58, 2: 35, 4: 24, 8: 15, }}, | |
99 | 4: { | |
100 | "L": {0: 640, 1: 187, 2: 114, 4: 78, 8: 48, }, | |
101 | "M": {0: 512, 1: 149, 2: 90, 4: 62, 8: 38, }, | |
102 | "Q": {0: 384, 1: 111, 2: 67, 4: 46, 8: 28, }, | |
103 | "H": {0: 288, 1: 82, 2: 50, 4: 34, 8: 21, }}, | |
104 | 5: { | |
105 | "L": {0: 864, 1: 255, 2: 154, 4: 106, 8: 65, }, | |
106 | "M": {0: 688, 1: 202, 2: 122, 4: 84, 8: 52, }, | |
107 | "Q": {0: 496, 1: 144, 2: 87, 4: 60, 8: 37, }, | |
108 | "H": {0: 368, 1: 106, 2: 64, 4: 44, 8: 27, }}, | |
109 | 6: { | |
110 | "L": {0: 1088, 1: 322, 2: 195, 4: 134, 8: 82, }, | |
111 | "M": {0: 864, 1: 255, 2: 154, 4: 106, 8: 65, }, | |
112 | "Q": {0: 608, 1: 178, 2: 108, 4: 74, 8: 45, }, | |
113 | "H": {0: 480, 1: 139, 2: 84, 4: 58, 8: 36, }}, | |
114 | 7: { | |
115 | "L": {0: 1248, 1: 370, 2: 224, 4: 154, 8: 95, }, | |
116 | "M": {0: 992, 1: 293, 2: 178, 4: 122, 8: 75, }, | |
117 | "Q": {0: 704, 1: 207, 2: 125, 4: 86, 8: 53, }, | |
118 | "H": {0: 528, 1: 154, 2: 93, 4: 64, 8: 39, }}, | |
119 | 8: { | |
120 | "L": {0: 1552, 1: 461, 2: 279, 4: 192, 8: 118, }, | |
121 | "M": {0: 1232, 1: 365, 2: 221, 4: 152, 8: 93, }, | |
122 | "Q": {0: 880, 1: 259, 2: 157, 4: 108, 8: 66, }, | |
123 | "H": {0: 688, 1: 202, 2: 122, 4: 84, 8: 52, }}, | |
124 | 9: { | |
125 | "L": {0: 1856, 1: 552, 2: 335, 4: 230, 8: 141, }, | |
126 | "M": {0: 1456, 1: 432, 2: 262, 4: 180, 8: 111, }, | |
127 | "Q": {0: 1056, 1: 312, 2: 189, 4: 130, 8: 80, }, | |
128 | "H": {0: 800, 1: 235, 2: 143, 4: 98, 8: 60, }}, | |
129 | 10: { | |
130 | "L": {0: 2192, 1: 652, 2: 395, 4: 271, 8: 167, }, | |
131 | "M": {0: 1728, 1: 513, 2: 311, 4: 213, 8: 131, }, | |
132 | "Q": {0: 1232, 1: 364, 2: 221, 4: 151, 8: 93, }, | |
133 | "H": {0: 976, 1: 288, 2: 174, 4: 119, 8: 74, }}, | |
134 | 11: { | |
135 | "L": {0: 2592, 1: 772, 2: 468, 4: 321, 8: 198, }, | |
136 | "M": {0: 2032, 1: 604, 2: 366, 4: 251, 8: 155, }, | |
137 | "Q": {0: 1440, 1: 427, 2: 259, 4: 177, 8: 109, }, | |
138 | "H": {0: 1120, 1: 331, 2: 200, 4: 137, 8: 85, }}, | |
139 | 12: { | |
140 | "L": {0: 2960, 1: 883, 2: 535, 4: 367, 8: 226, }, | |
141 | "M": {0: 2320, 1: 691, 2: 419, 4: 287, 8: 177, }, | |
142 | "Q": {0: 1648, 1: 489, 2: 296, 4: 203, 8: 125, }, | |
143 | "H": {0: 1264, 1: 374, 2: 227, 4: 155, 8: 96, }}, | |
144 | 13: { | |
145 | "L": {0: 3424, 1: 1022, 2: 619, 4: 425, 8: 262, }, | |
146 | "M": {0: 2672, 1: 796, 2: 483, 4: 331, 8: 204, }, | |
147 | "Q": {0: 1952, 1: 580, 2: 352, 4: 241, 8: 149, }, | |
148 | "H": {0: 1440, 1: 427, 2: 259, 4: 177, 8: 109, }}, | |
149 | 14: { | |
150 | "L": {0: 3688, 1: 1101, 2: 667, 4: 458, 8: 282, }, | |
151 | "M": {0: 2920, 1: 871, 2: 528, 4: 362, 8: 223, }, | |
152 | "Q": {0: 2088, 1: 621, 2: 376, 4: 258, 8: 159, }, | |
153 | "H": {0: 1576, 1: 468, 2: 283, 4: 194, 8: 120, }}, | |
154 | 15: { | |
155 | "L": {0: 4184, 1: 1250, 2: 758, 4: 520, 8: 320, }, | |
156 | "M": {0: 3320, 1: 991, 2: 600, 4: 412, 8: 254, }, | |
157 | "Q": {0: 2360, 1: 703, 2: 426, 4: 292, 8: 180, }, | |
158 | "H": {0: 1784, 1: 530, 2: 321, 4: 220, 8: 136, }}, | |
159 | 16: { | |
160 | "L": {0: 4712, 1: 1408, 2: 854, 4: 586, 8: 361, }, | |
161 | "M": {0: 3624, 1: 1082, 2: 656, 4: 450, 8: 277, }, | |
162 | "Q": {0: 2600, 1: 775, 2: 470, 4: 322, 8: 198, }, | |
163 | "H": {0: 2024, 1: 602, 2: 365, 4: 250, 8: 154, }}, | |
164 | 17: { | |
165 | "L": {0: 5176, 1: 1548, 2: 938, 4: 644, 8: 397, }, | |
166 | "M": {0: 4056, 1: 1212, 2: 734, 4: 504, 8: 310, }, | |
167 | "Q": {0: 2936, 1: 876, 2: 531, 4: 364, 8: 224, }, | |
168 | "H": {0: 2264, 1: 674, 2: 408, 4: 280, 8: 173, }}, | |
169 | 18: { | |
170 | "L": {0: 5768, 1: 1725, 2: 1046, 4: 718, 8: 442, }, | |
171 | "M": {0: 4504, 1: 1346, 2: 816, 4: 560, 8: 345, }, | |
172 | "Q": {0: 3176, 1: 948, 2: 574, 4: 394, 8: 243, }, | |
173 | "H": {0: 2504, 1: 746, 2: 452, 4: 310, 8: 191, }}, | |
174 | 19: { | |
175 | "L": {0: 6360, 1: 1903, 2: 1153, 4: 792, 8: 488, }, | |
176 | "M": {0: 5016, 1: 1500, 2: 909, 4: 624, 8: 384, }, | |
177 | "Q": {0: 3560, 1: 1063, 2: 644, 4: 442, 8: 272, }, | |
178 | "H": {0: 2728, 1: 813, 2: 493, 4: 338, 8: 208, }}, | |
179 | 20: { | |
180 | "L": {0: 6888, 1: 2061, 2: 1249, 4: 858, 8: 528, }, | |
181 | "M": {0: 5352, 1: 1600, 2: 970, 4: 666, 8: 410, }, | |
182 | "Q": {0: 3880, 1: 1159, 2: 702, 4: 482, 8: 297, }, | |
183 | "H": {0: 3080, 1: 919, 2: 557, 4: 382, 8: 235, }}, | |
184 | 21: { | |
185 | "L": {0: 7456, 1: 2232, 2: 1352, 4: 929, 8: 572, }, | |
186 | "M": {0: 5712, 1: 1708, 2: 1035, 4: 711, 8: 438, }, | |
187 | "Q": {0: 4096, 1: 1224, 2: 742, 4: 509, 8: 314, }, | |
188 | "H": {0: 3248, 1: 969, 2: 587, 4: 403, 8: 248, }}, | |
189 | 22: { | |
190 | "L": {0: 8048, 1: 2409, 2: 1460, 4: 1003, 8: 618, }, | |
191 | "M": {0: 6256, 1: 1872, 2: 1134, 4: 779, 8: 480, }, | |
192 | "Q": {0: 4544, 1: 1358, 2: 823, 4: 565, 8: 348, }, | |
193 | "H": {0: 3536, 1: 1056, 2: 640, 4: 439, 8: 270, }}, | |
194 | 23: { | |
195 | "L": {0: 8752, 1: 2620, 2: 1588, 4: 1091, 8: 672, }, | |
196 | "M": {0: 6880, 1: 2059, 2: 1248, 4: 857, 8: 528, }, | |
197 | "Q": {0: 4912, 1: 1468, 2: 890, 4: 611, 8: 376, }, | |
198 | "H": {0: 3712, 1: 1108, 2: 672, 4: 461, 8: 284, }}, | |
199 | 24: { | |
200 | "L": {0: 9392, 1: 2812, 2: 1704, 4: 1171, 8: 721, }, | |
201 | "M": {0: 7312, 1: 2188, 2: 1326, 4: 911, 8: 561, }, | |
202 | "Q": {0: 5312, 1: 1588, 2: 963, 4: 661, 8: 407, }, | |
203 | "H": {0: 4112, 1: 1228, 2: 744, 4: 511, 8: 315, }}, | |
204 | 25: { | |
205 | "L": {0: 10208, 1: 3057, 2: 1853, 4: 1273, 8: 784, }, | |
206 | "M": {0: 8000, 1: 2395, 2: 1451, 4: 997, 8: 614, }, | |
207 | "Q": {0: 5744, 1: 1718, 2: 1041, 4: 715, 8: 440, }, | |
208 | "H": {0: 4304, 1: 1286, 2: 779, 4: 535, 8: 330, }}, | |
209 | 26: { | |
210 | "L": {0: 10960, 1: 3283, 2: 1990, 4: 1367, 8: 842, }, | |
211 | "M": {0: 8496, 1: 2544, 2: 1542, 4: 1059, 8: 652, }, | |
212 | "Q": {0: 6032, 1: 1804, 2: 1094, 4: 751, 8: 462, }, | |
213 | "H": {0: 4768, 1: 1425, 2: 864, 4: 593, 8: 365, }}, | |
214 | 27: { | |
215 | "L": {0: 11744, 1: 3514, 2: 2132, 4: 1465, 8: 902, }, | |
216 | "M": {0: 9024, 1: 2701, 2: 1637, 4: 1125, 8: 692, }, | |
217 | "Q": {0: 6464, 1: 1933, 2: 1172, 4: 805, 8: 496, }, | |
218 | "H": {0: 5024, 1: 1501, 2: 910, 4: 625, 8: 385, }}, | |
219 | 28: { | |
220 | "L": {0: 12248, 1: 3669, 2: 2223, 4: 1528, 8: 940, }, | |
221 | "M": {0: 9544, 1: 2857, 2: 1732, 4: 1190, 8: 732, }, | |
222 | "Q": {0: 6968, 1: 2085, 2: 1263, 4: 868, 8: 534, }, | |
223 | "H": {0: 5288, 1: 1581, 2: 958, 4: 658, 8: 405, }}, | |
224 | 29: { | |
225 | "L": {0: 13048, 1: 3909, 2: 2369, 4: 1628, 8: 1002, }, | |
226 | "M": {0: 10136, 1: 3035, 2: 1839, 4: 1264, 8: 778, }, | |
227 | "Q": {0: 7288, 1: 2181, 2: 1322, 4: 908, 8: 559, }, | |
228 | "H": {0: 5608, 1: 1677, 2: 1016, 4: 698, 8: 430, }}, | |
229 | 30: { | |
230 | "L": {0: 13880, 1: 4158, 2: 2520, 4: 1732, 8: 1066, }, | |
231 | "M": {0: 10984, 1: 3289, 2: 1994, 4: 1370, 8: 843, }, | |
232 | "Q": {0: 7880, 1: 2358, 2: 1429, 4: 982, 8: 604, }, | |
233 | "H": {0: 5960, 1: 1782, 2: 1080, 4: 742, 8: 457, }}, | |
234 | 31: { | |
235 | "L": {0: 14744, 1: 4417, 2: 2677, 4: 1840, 8: 1132, }, | |
236 | "M": {0: 11640, 1: 3486, 2: 2113, 4: 1452, 8: 894, }, | |
237 | "Q": {0: 8264, 1: 2473, 2: 1499, 4: 1030, 8: 634, }, | |
238 | "H": {0: 6344, 1: 1897, 2: 1150, 4: 790, 8: 486, }}, | |
239 | 32: { | |
240 | "L": {0: 15640, 1: 4686, 2: 2840, 4: 1952, 8: 1201, }, | |
241 | "M": {0: 12328, 1: 3693, 2: 2238, 4: 1538, 8: 947, }, | |
242 | "Q": {0: 8920, 1: 2670, 2: 1618, 4: 1112, 8: 684, }, | |
243 | "H": {0: 6760, 1: 2022, 2: 1226, 4: 842, 8: 518, }}, | |
244 | 33: { | |
245 | "L": {0: 16568, 1: 4965, 2: 3009, 4: 2068, 8: 1273, }, | |
246 | "M": {0: 13048, 1: 3909, 2: 2369, 4: 1628, 8: 1002, }, | |
247 | "Q": {0: 9368, 1: 2805, 2: 1700, 4: 1168, 8: 719, }, | |
248 | "H": {0: 7208, 1: 2157, 2: 1307, 4: 898, 8: 553, }}, | |
249 | 34: { | |
250 | "L": {0: 17528, 1: 5253, 2: 3183, 4: 2188, 8: 1347, }, | |
251 | "M": {0: 13800, 1: 4134, 2: 2506, 4: 1722, 8: 1060, }, | |
252 | "Q": {0: 9848, 1: 2949, 2: 1787, 4: 1228, 8: 756, }, | |
253 | "H": {0: 7688, 1: 2301, 2: 1394, 4: 958, 8: 590, }}, | |
254 | 35: { | |
255 | "L": {0: 18448, 1: 5529, 2: 3351, 4: 2303, 8: 1417, }, | |
256 | "M": {0: 14496, 1: 4343, 2: 2632, 4: 1809, 8: 1113, }, | |
257 | "Q": {0: 10288, 1: 3081, 2: 1867, 4: 1283, 8: 790, }, | |
258 | "H": {0: 7888, 1: 2361, 2: 1431, 4: 983, 8: 605, }}, | |
259 | 36: { | |
260 | "L": {0: 19472, 1: 5836, 2: 3537, 4: 2431, 8: 1496, }, | |
261 | "M": {0: 15312, 1: 4588, 2: 2780, 4: 1911, 8: 1176, }, | |
262 | "Q": {0: 10832, 1: 3244, 2: 1966, 4: 1351, 8: 832, }, | |
263 | "H": {0: 8432, 1: 2524, 2: 1530, 4: 1051, 8: 647, }}, | |
264 | 37: { | |
265 | "L": {0: 20528, 1: 6153, 2: 3729, 4: 2563, 8: 1577, }, | |
266 | "M": {0: 15936, 1: 4775, 2: 2894, 4: 1989, 8: 1224, }, | |
267 | "Q": {0: 11408, 1: 3417, 2: 2071, 4: 1423, 8: 876, }, | |
268 | "H": {0: 8768, 1: 2625, 2: 1591, 4: 1093, 8: 673, }}, | |
269 | 38: { | |
270 | "L": {0: 21616, 1: 6479, 2: 3927, 4: 2699, 8: 1661, }, | |
271 | "M": {0: 16816, 1: 5039, 2: 3054, 4: 2099, 8: 1292, }, | |
272 | "Q": {0: 12016, 1: 3599, 2: 2181, 4: 1499, 8: 923, }, | |
273 | "H": {0: 9136, 1: 2735, 2: 1658, 4: 1139, 8: 701, }}, | |
274 | 39: { | |
275 | "L": {0: 22496, 1: 6743, 2: 4087, 4: 2809, 8: 1729, }, | |
276 | "M": {0: 17728, 1: 5313, 2: 3220, 4: 2213, 8: 1362, }, | |
277 | "Q": {0: 12656, 1: 3791, 2: 2298, 4: 1579, 8: 972, }, | |
278 | "H": {0: 9776, 1: 2927, 2: 1774, 4: 1219, 8: 750, }}, | |
279 | 40: { | |
280 | "L": {0: 23648, 1: 7089, 2: 4296, 4: 2953, 8: 1817, }, | |
281 | "M": {0: 18672, 1: 5596, 2: 3391, 4: 2331, 8: 1435, }, | |
282 | "Q": {0: 13328, 1: 3993, 2: 2420, 4: 1663, 8: 1024, }, | |
283 | "H": {0: 10208, 1: 3057, 2: 1852, 4: 1273, 8: 784, }} | |
284 | } | |
285 | ||
286 | #: This table defines the "Error Correction Code Words and Block Information." | |
287 | #: The table lists the number of error correction words that are required | |
288 | #: to be generated for each version and error correction level. The table | |
289 | #: is accessed by first using the version number as a key and then the | |
290 | #: error level. The array values correspond to these columns from the source | |
291 | #: table: | |
292 | #: | |
293 | #: +----------------------------+ | |
294 | #: |0 | EC Code Words Per Block | | |
295 | #: +----------------------------+ | |
296 | #: |1 | Block 1 Count | | |
297 | #: +----------------------------+ | |
298 | #: |2 | Block 1 Data Code Words | | |
299 | #: +----------------------------+ | |
300 | #: |3 | Block 2 Count | | |
301 | #: +----------------------------+ | |
302 | #: |4 | Block 2 Data Code Words | | |
303 | #: +----------------------------+ | |
304 | #: | |
305 | #: This table was taken from: | |
306 | #: | |
307 | #: http://www.thonky.com/qr-code-tutorial/error-correction-table/ | |
308 | eccwbi = { | |
309 | 1: { | |
310 | 'L': [7, 1, 19, 0, 0, ], | |
311 | 'M': [10, 1, 16, 0, 0, ], | |
312 | 'Q': [13, 1, 13, 0, 0, ], | |
313 | 'H': [17, 1, 9, 0, 0, ], | |
314 | }, | |
315 | 2: { | |
316 | 'L': [10, 1, 34, 0, 0, ], | |
317 | 'M': [16, 1, 28, 0, 0, ], | |
318 | 'Q': [22, 1, 22, 0, 0, ], | |
319 | 'H': [28, 1, 16, 0, 0, ], | |
320 | }, | |
321 | 3: { | |
322 | 'L': [15, 1, 55, 0, 0, ], | |
323 | 'M': [26, 1, 44, 0, 0, ], | |
324 | 'Q': [18, 2, 17, 0, 0, ], | |
325 | 'H': [22, 2, 13, 0, 0, ], | |
326 | }, | |
327 | 4: { | |
328 | 'L': [20, 1, 80, 0, 0, ], | |
329 | 'M': [18, 2, 32, 0, 0, ], | |
330 | 'Q': [26, 2, 24, 0, 0, ], | |
331 | 'H': [16, 4, 9, 0, 0, ], | |
332 | }, | |
333 | 5: { | |
334 | 'L': [26, 1, 108, 0, 0, ], | |
335 | 'M': [24, 2, 43, 0, 0, ], | |
336 | 'Q': [18, 2, 15, 2, 16, ], | |
337 | 'H': [22, 2, 11, 2, 12, ], | |
338 | }, | |
339 | 6: { | |
340 | 'L': [18, 2, 68, 0, 0, ], | |
341 | 'M': [16, 4, 27, 0, 0, ], | |
342 | 'Q': [24, 4, 19, 0, 0, ], | |
343 | 'H': [28, 4, 15, 0, 0, ], | |
344 | }, | |
345 | 7: { | |
346 | 'L': [20, 2, 78, 0, 0, ], | |
347 | 'M': [18, 4, 31, 0, 0, ], | |
348 | 'Q': [18, 2, 14, 4, 15, ], | |
349 | 'H': [26, 4, 13, 1, 14, ], | |
350 | }, | |
351 | 8: { | |
352 | 'L': [24, 2, 97, 0, 0, ], | |
353 | 'M': [22, 2, 38, 2, 39, ], | |
354 | 'Q': [22, 4, 18, 2, 19, ], | |
355 | 'H': [26, 4, 14, 2, 15, ], | |
356 | }, | |
357 | 9: { | |
358 | 'L': [30, 2, 116, 0, 0, ], | |
359 | 'M': [22, 3, 36, 2, 37, ], | |
360 | 'Q': [20, 4, 16, 4, 17, ], | |
361 | 'H': [24, 4, 12, 4, 13, ], | |
362 | }, | |
363 | 10: { | |
364 | 'L': [18, 2, 68, 2, 69, ], | |
365 | 'M': [26, 4, 43, 1, 44, ], | |
366 | 'Q': [24, 6, 19, 2, 20, ], | |
367 | 'H': [28, 6, 15, 2, 16, ], | |
368 | }, | |
369 | 11: { | |
370 | 'L': [20, 4, 81, 0, 0, ], | |
371 | 'M': [30, 1, 50, 4, 51, ], | |
372 | 'Q': [28, 4, 22, 4, 23, ], | |
373 | 'H': [24, 3, 12, 8, 13, ], | |
374 | }, | |
375 | 12: { | |
376 | 'L': [24, 2, 92, 2, 93, ], | |
377 | 'M': [22, 6, 36, 2, 37, ], | |
378 | 'Q': [26, 4, 20, 6, 21, ], | |
379 | 'H': [28, 7, 14, 4, 15, ], | |
380 | }, | |
381 | 13: { | |
382 | 'L': [26, 4, 107, 0, 0, ], | |
383 | 'M': [22, 8, 37, 1, 38, ], | |
384 | 'Q': [24, 8, 20, 4, 21, ], | |
385 | 'H': [22, 12, 11, 4, 12, ], | |
386 | }, | |
387 | 14: { | |
388 | 'L': [30, 3, 115, 1, 116, ], | |
389 | 'M': [24, 4, 40, 5, 41, ], | |
390 | 'Q': [20, 11, 16, 5, 17, ], | |
391 | 'H': [24, 11, 12, 5, 13, ], | |
392 | }, | |
393 | 15: { | |
394 | 'L': [22, 5, 87, 1, 88, ], | |
395 | 'M': [24, 5, 41, 5, 42, ], | |
396 | 'Q': [30, 5, 24, 7, 25, ], | |
397 | 'H': [24, 11, 12, 7, 13, ], | |
398 | }, | |
399 | 16: { | |
400 | 'L': [24, 5, 98, 1, 99, ], | |
401 | 'M': [28, 7, 45, 3, 46, ], | |
402 | 'Q': [24, 15, 19, 2, 20, ], | |
403 | 'H': [30, 3, 15, 13, 16, ], | |
404 | }, | |
405 | 17: { | |
406 | 'L': [28, 1, 107, 5, 108, ], | |
407 | 'M': [28, 10, 46, 1, 47, ], | |
408 | 'Q': [28, 1, 22, 15, 23, ], | |
409 | 'H': [28, 2, 14, 17, 15, ], | |
410 | }, | |
411 | 18: { | |
412 | 'L': [30, 5, 120, 1, 121, ], | |
413 | 'M': [26, 9, 43, 4, 44, ], | |
414 | 'Q': [28, 17, 22, 1, 23, ], | |
415 | 'H': [28, 2, 14, 19, 15, ], | |
416 | }, | |
417 | 19: { | |
418 | 'L': [28, 3, 113, 4, 114, ], | |
419 | 'M': [26, 3, 44, 11, 45, ], | |
420 | 'Q': [26, 17, 21, 4, 22, ], | |
421 | 'H': [26, 9, 13, 16, 14, ], | |
422 | }, | |
423 | 20: { | |
424 | 'L': [28, 3, 107, 5, 108, ], | |
425 | 'M': [26, 3, 41, 13, 42, ], | |
426 | 'Q': [30, 15, 24, 5, 25, ], | |
427 | 'H': [28, 15, 15, 10, 16, ], | |
428 | }, | |
429 | 21: { | |
430 | 'L': [28, 4, 116, 4, 117, ], | |
431 | 'M': [26, 17, 42, 0, 0, ], | |
432 | 'Q': [28, 17, 22, 6, 23, ], | |
433 | 'H': [30, 19, 16, 6, 17, ], | |
434 | }, | |
435 | 22: { | |
436 | 'L': [28, 2, 111, 7, 112, ], | |
437 | 'M': [28, 17, 46, 0, 0, ], | |
438 | 'Q': [30, 7, 24, 16, 25, ], | |
439 | 'H': [24, 34, 13, 0, 0, ], | |
440 | }, | |
441 | 23: { | |
442 | 'L': [30, 4, 121, 5, 122, ], | |
443 | 'M': [28, 4, 47, 14, 48, ], | |
444 | 'Q': [30, 11, 24, 14, 25, ], | |
445 | 'H': [30, 16, 15, 14, 16, ], | |
446 | }, | |
447 | 24: { | |
448 | 'L': [30, 6, 117, 4, 118, ], | |
449 | 'M': [28, 6, 45, 14, 46, ], | |
450 | 'Q': [30, 11, 24, 16, 25, ], | |
451 | 'H': [30, 30, 16, 2, 17, ], | |
452 | }, | |
453 | 25: { | |
454 | 'L': [26, 8, 106, 4, 107, ], | |
455 | 'M': [28, 8, 47, 13, 48, ], | |
456 | 'Q': [30, 7, 24, 22, 25, ], | |
457 | 'H': [30, 22, 15, 13, 16, ], | |
458 | }, | |
459 | 26: { | |
460 | 'L': [28, 10, 114, 2, 115, ], | |
461 | 'M': [28, 19, 46, 4, 47, ], | |
462 | 'Q': [28, 28, 22, 6, 23, ], | |
463 | 'H': [30, 33, 16, 4, 17, ], | |
464 | }, | |
465 | 27: { | |
466 | 'L': [30, 8, 122, 4, 123, ], | |
467 | 'M': [28, 22, 45, 3, 46, ], | |
468 | 'Q': [30, 8, 23, 26, 24, ], | |
469 | 'H': [30, 12, 15, 28, 16, ], | |
470 | }, | |
471 | 28: { | |
472 | 'L': [30, 3, 117, 10, 118, ], | |
473 | 'M': [28, 3, 45, 23, 46, ], | |
474 | 'Q': [30, 4, 24, 31, 25, ], | |
475 | 'H': [30, 11, 15, 31, 16, ], | |
476 | }, | |
477 | 29: { | |
478 | 'L': [30, 7, 116, 7, 117, ], | |
479 | 'M': [28, 21, 45, 7, 46, ], | |
480 | 'Q': [30, 1, 23, 37, 24, ], | |
481 | 'H': [30, 19, 15, 26, 16, ], | |
482 | }, | |
483 | 30: { | |
484 | 'L': [30, 5, 115, 10, 116, ], | |
485 | 'M': [28, 19, 47, 10, 48, ], | |
486 | 'Q': [30, 15, 24, 25, 25, ], | |
487 | 'H': [30, 23, 15, 25, 16, ], | |
488 | }, | |
489 | 31: { | |
490 | 'L': [30, 13, 115, 3, 116, ], | |
491 | 'M': [28, 2, 46, 29, 47, ], | |
492 | 'Q': [30, 42, 24, 1, 25, ], | |
493 | 'H': [30, 23, 15, 28, 16, ], | |
494 | }, | |
495 | 32: { | |
496 | 'L': [30, 17, 115, 0, 0, ], | |
497 | 'M': [28, 10, 46, 23, 47, ], | |
498 | 'Q': [30, 10, 24, 35, 25, ], | |
499 | 'H': [30, 19, 15, 35, 16, ], | |
500 | }, | |
501 | 33: { | |
502 | 'L': [30, 17, 115, 1, 116, ], | |
503 | 'M': [28, 14, 46, 21, 47, ], | |
504 | 'Q': [30, 29, 24, 19, 25, ], | |
505 | 'H': [30, 11, 15, 46, 16, ], | |
506 | }, | |
507 | 34: { | |
508 | 'L': [30, 13, 115, 6, 116, ], | |
509 | 'M': [28, 14, 46, 23, 47, ], | |
510 | 'Q': [30, 44, 24, 7, 25, ], | |
511 | 'H': [30, 59, 16, 1, 17, ], | |
512 | }, | |
513 | 35: { | |
514 | 'L': [30, 12, 121, 7, 122, ], | |
515 | 'M': [28, 12, 47, 26, 48, ], | |
516 | 'Q': [30, 39, 24, 14, 25, ], | |
517 | 'H': [30, 22, 15, 41, 16, ], | |
518 | }, | |
519 | 36: { | |
520 | 'L': [30, 6, 121, 14, 122, ], | |
521 | 'M': [28, 6, 47, 34, 48, ], | |
522 | 'Q': [30, 46, 24, 10, 25, ], | |
523 | 'H': [30, 2, 15, 64, 16, ], | |
524 | }, | |
525 | 37: { | |
526 | 'L': [30, 17, 122, 4, 123, ], | |
527 | 'M': [28, 29, 46, 14, 47, ], | |
528 | 'Q': [30, 49, 24, 10, 25, ], | |
529 | 'H': [30, 24, 15, 46, 16, ], | |
530 | }, | |
531 | 38: { | |
532 | 'L': [30, 4, 122, 18, 123, ], | |
533 | 'M': [28, 13, 46, 32, 47, ], | |
534 | 'Q': [30, 48, 24, 14, 25, ], | |
535 | 'H': [30, 42, 15, 32, 16, ], | |
536 | }, | |
537 | 39: { | |
538 | 'L': [30, 20, 117, 4, 118, ], | |
539 | 'M': [28, 40, 47, 7, 48, ], | |
540 | 'Q': [30, 43, 24, 22, 25, ], | |
541 | 'H': [30, 10, 15, 67, 16, ], | |
542 | }, | |
543 | 40: { | |
544 | 'L': [30, 19, 118, 6, 119, ], | |
545 |