1
0
mirror of https://github.com/x-hw/amazing-qr.git synced 2025-07-15 01:24:37 +02:00
This commit is contained in:
sylnsfar
2016-08-30 20:43:52 +08:00
parent dc1c48a421
commit 0f18eebedc
9 changed files with 121 additions and 128 deletions

View File

@ -1,2 +1,17 @@
# QR-Code
QR Code in Python Python QR二维码生成器
QR Code in Python
Python QR二维码生成器
### Usage 用法
```python
python myqrcode.py [-l [L,M,Q,H]] xxxxxx
```
### Example 示例
```python
python myqrcode.py -l H https://github.com/sylnsfar/QR-Code
```

13
data.py
View File

@ -103,15 +103,4 @@ def get_cci(ver, mode, str):
cci = bin(len(str))[2:]
cci = '0' * (cci_len - len(cci)) + cci
return cci
if __name__ == '__main__':
# test:
c,m = encode('M', 'HELLO WORLD')
print(c,m)
print(bool(m=='00100000010110110000101101111000110100010111001011011100010011010100001101000000111011000001000111101100'))
print(len(m))
print(all(grouping_list[v][l][3]==0 or grouping_list[v][l][3]-1==grouping_list[v][l][1] for v in range(40) for l in range(4)))
return cci

48
draw.py
View File

@ -1,46 +1,22 @@
# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw
import os
# test:
m1 = [[1]*7+[0]*7+[1]*7,
[1,0,0,0,0,0,1]+[0]*7+[1,0,0,0,0,0,1],
[1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1],
[1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1],
[1,0,1,1,1,0,1]+[0]*7+[1,0,1,1,1,0,1],
[1,0,0,0,0,0,1]+[0]*7+[1,0,0,0,0,0,1],
[1]*7+[0,1,0,1,0,1,0]+[1]*7,
[0]*21,
[0]*6+[1]+[0]*14,
[0]*21,
[0]*6+[1]+[0]*14,
[0]*21,
[0]*6+[1]+[0]*14,
[0]*21,
[1]*7+[0]*14,
[1,0,0,0,0,0,1]+[0]*14,
[1,0,1,1,1,0,1]+[0]*14,
[1,0,1,1,1,0,1]+[0]*14,
[1,0,1,1,1,0,1]+[0]*14,
[1,0,0,0,0,0,1]+[0]*14,
[1]*7+[0]*14
]
def draw_qrcode(qrmatrix):
x, y = 0, 0
def draw_qrcode(abspath, qrmatrix):
unit_len = 9
pic = Image.new('1', [len(qrmatrix)*unit_len]*2, 'white')
x = y = 4*unit_len
pic = Image.new('1', [(len(qrmatrix)+8)*unit_len]*2, 'white')
draw = ImageDraw.Draw(pic)
for a in range(len(qrmatrix)):
for b in range(len(qrmatrix[a])):
if qrmatrix[a][b]:
for line in qrmatrix:
for module in line:
if module:
draw.rectangle([x,y,x+unit_len,y+unit_len], fill = 0)
x += unit_len
x, y = 0, y+unit_len
x, y = 4*unit_len, y+unit_len
pic.save('qrcode.jpg')
pic.show()
# test:
#draw_qrcode(m1)
saving = os.path.join(abspath, 'qrcode.jpg')
pic.save(saving)
#pic.show()
return saving

40
ecc.py
View File

@ -18,16 +18,16 @@ def get_ecc(dc, ecc_num):
return remainder
def divide(MP, *GP):
po2 = get_power_of_2_list()
log = get_log_list(po2)
GP = list(GP)
for i in range(len(GP)):
GP[i] += log[MP[0]]
if GP[i] > 255:
GP[i] %= 255
GP[i] = po2[GP[i]]
return XOR(GP, *MP)
if MP[0]:
GP = list(GP)
for i in range(len(GP)):
GP[i] += log[MP[0]]
if GP[i] > 255:
GP[i] %= 255
GP[i] = po2[GP[i]]
return XOR(GP, *MP)
else:
return MP[1:]
def XOR(GP, *MP):
@ -39,22 +39,6 @@ def XOR(GP, *MP):
GP += [0] * a
remainder = []
for i in range(len(MP)):
for i in range(1, len(MP)):
remainder.append(MP[i]^GP[i])
remainder = [i for i in remainder if i]
return remainder
def get_power_of_2_list():
po2 = [1]
for i in range(255):
a = po2[i] * 2
if a > 255:
a ^= 285
po2.append(a)
return po2
def get_log_list(po2):
log = [None]*256
for i in range(255):
log[po2[i]] = i
return log
return remainder

View File

@ -26,9 +26,9 @@ def get_qrmatrix(ver, ecl, bits):
# Data Masking
mask_num, qrmatrix = mask(maskmatrix, qrmatrix)
# Format and Version Information
# Format Information
add_format_and_version_string(ver, ecl, mask_num, qrmatrix)
return qrmatrix
def add_finder_and_separator(m):
@ -96,7 +96,6 @@ def mask(mm, m):
best = scores.index(min(scores))
return best, mps[best]
def get_mask_patterns(mm):
def formula(i, row, column):
if i == 0:
@ -177,4 +176,19 @@ def compute_score(m):
return 2*s if s >=0 else -2*s
score = evaluation1(m) + evaluation2(m)+ evaluation3(m) + evaluation4(m)
return score
return score
def add_format_and_version_string(ver, ecl, mask_num, m):
fs = [int(i) for i in format_info_str[lindex[ecl]][mask_num]]
for j in range(6):
m[8][j] = m[-j-1][8] = fs[j]
m[8][-j-1] = m[j][8] = fs[-j-1]
m[8][7] = m[-7][8] = fs[6]
m[8][8] = m[8][-8] = fs[7]
m[7][8] = m[8][-7] = fs[8]
if ver > 6:
vs = (int(i) for i in version_info_str[ver-7])
for j in range(5, -1, -1):
for i in (-9, -10, -11):
m[i][j] = m[j][i] = next(vs)

View File

@ -76,4 +76,32 @@ required_remainder_bits = (0,7,7,7,7,7,0,0,0,0,0,0,0,3,3,3,3,3,3,3,4,4,4,4,4,4,4
# Alignment Pattern Locations
alig_location = [
(6, 18), (6, 22), (6, 26), (6, 30), (6, 34), (6, 22, 38), (6, 24, 42), (6, 26, 46), (6, 28, 50), (6, 30, 54), (6, 32, 58), (6, 34, 62), (6, 26, 46, 66), (6, 26, 48, 70), (6, 26, 50, 74), (6, 30, 54, 78), (6, 30, 56, 82), (6, 30, 58, 86), (6, 34, 62, 90), (6, 28, 50, 72, 94), (6, 26, 50, 74, 98), (6, 30, 54, 78, 102), (6, 28, 54, 80, 106), (6, 32, 58, 84, 110), (6, 30, 58, 86, 114), (6, 34, 62, 90, 118), (6, 26, 50, 74, 98, 122), (6, 30, 54, 78, 102, 126), (6, 26, 52, 78, 104, 130), (6, 30, 56, 82, 108, 134), (6, 34, 60, 86, 112, 138), (6, 30, 58, 86, 114, 142), (6, 34, 62, 90, 118, 146), (6, 30, 54, 78, 102, 126, 150), (6, 24, 50, 76, 102, 128, 154), (6, 28, 54, 80, 106, 132, 158), (6, 32, 58, 84, 110, 136, 162), (6, 26, 54, 82, 110, 138, 166), (6, 30, 58, 86, 114, 142, 170)
]
# List of all Format Information Strings
# [
# level1[mask_pattern0, mask_pattern1, mask_...3,...],
# level2[...],
# level3[...],
# level4[...]
# ]
format_info_str = [
['111011111000100', '111001011110011', '111110110101010', '111100010011101', '110011000101111', '110001100011000', '110110001000001', '110100101110110'], ['101010000010010', '101000100100101', '101111001111100', '101101101001011', '100010111111001', '100000011001110', '100111110010111', '100101010100000'], ['011010101011111', '011000001101000', '011111100110001', '011101000000110', '010010010110100', '010000110000011', '010111011011010', '010101111101101'], ['001011010001001', '001001110111110', '001110011100111', '001100111010000', '000011101100010', '000001001010101', '000110100001100', '000100000111011']
]
# Version Information Strings
version_info_str = [
'000111110010010100', '001000010110111100', '001001101010011001', '001010010011010011', '001011101111110110', '001100011101100010', '001101100001000111', '001110011000001101', '001111100100101000', '010000101101111000', '010001010001011101', '010010101000010111', '010011010100110010', '010100100110100110', '010101011010000011', '010110100011001001', '010111011111101100', '011000111011000100', '011001000111100001', '011010111110101011', '011011000010001110', '011100110000011010', '011101001100111111', '011110110101110101', '011111001001010000', '100000100111010101', '100001011011110000', '100010100010111010', '100011011110011111', '100100101100001011', '100101010000101110', '100110101001100100', '100111010101000001', '101000110001101001'
]
# powers of 2 list
po2 = [
1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1
]
# log list
log = [
None, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175
]

View File

@ -1,38 +1,42 @@
# -*- coding: utf-8 -*-
import data, ECC, structure, matrix, draw
import data, ECC, structure, matrix, draw, os
# ecl: Error Correction Level(L,M,Q,H)
def get_qrcode(ecl, str):
try:
# Data Coding
ver, data_codewords = data.encode(ecl, str)
ndc = 0
for i in range(len(data_codewords)):
ndc += len(data_codewords[i])
if ecl not in 'LMQH':
print('Level Error: please choose one of L,M,Q,H!')
else:
try:
# Data Coding
ver, data_codewords = data.encode(ecl, str)
# Error Correction Coding
ecc = ECC.encode(ver, ecl, data_codewords)
ndc = 0
for i in range(len(data_codewords)):
ndc += len(data_codewords[i])
# Structure final bits
final_bits = structure.structure_final_bits(ver, ecl, data_codewords, ecc)
# Get the QR Matrix
qrmatrix = matrix.get_qrmatrix(ver, ecl, final_bits)
# Error Correction Coding
ecc = ECC.encode(ver, ecl, data_codewords)
# Draw the picture
draw.draw_qrcode(qrmatrix)
except UnicodeEncodeError:
print('Error input!!')
# Structure final bits
final_bits = structure.structure_final_bits(ver, ecl, data_codewords, ecc)
# Get the QR Matrix
qrmatrix = matrix.get_qrmatrix(ver, ecl, final_bits)
# Draw the picture and Save it, then return the absolute path
return draw.draw_qrcode(os.path.abspath('.'), qrmatrix)
except UnicodeEncodeError:
print('Input Error: please read the README file for the supported characters!!')
if __name__ == '__main__':
# test:
str = 'HELLO WORLD'
str2 = 'http://www.thonky.com/qr-code-tutorial/log-antilog-table'
err = '💩'
get_qrcode('Q',str)
import argparse, os
argparser = argparse.ArgumentParser()
argparser.add_argument('WORDs', help='The words to produce you QR-code picture, like a URL or a sentence. Please read the README file for the supported characters.')
argparser.add_argument('-l', '--level', help='Use this argument to choose an Error-Correction-Level: L(Low), M(Medium), Q(Quartile), H(High). Otherwise, just use the default one: Q')
args = argparser.parse_args()
# the default level is Q
ecl = args.level if args.level else 'Q'
path = get_qrcode(ecl, args.WORDs)
if path is not None:
print('Succeed! Check out your QR-code at', path)

BIN
qrcode.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -24,21 +24,4 @@ def interleave_ecc(ecc):
ie = []
for t in zip(*ecc):
ie += list(t)
return ie
if __name__ == '__main__':
dc = [[67,85,70,134,87,38,85,194,119,50,6,18,6,103,38],
[246,246,66,7,118,134,242,7,38,86,22,198,199,146,6],
[182,230,247,119,50,7,118,134,87,38,82,6,134,151,50,7],
[70,247,118,86,194,6,151,50,16,236,17,236,17,236,17,236]]
ecc = [[213, 199, 11, 45, 115, 247, 241, 223, 229, 248, 154, 117, 154, 111, 86, 161, 111, 39],
[87, 204, 96, 60, 202, 182, 124, 157, 200, 134, 27, 129, 209, 17, 163, 163, 120, 133],
[148, 116, 177, 212, 76, 133, 75, 242, 238, 76, 195, 230, 189, 10, 108, 240, 192, 141],
[235, 159, 5, 173, 24, 147, 59, 33, 106, 40, 255, 172, 82, 2, 131, 32, 178, 236]]
v = 5
l = 'Q'
finalbits = structure_final_bits(v,l,dc,ecc)
print(finalbits)
a = '01000011111101101011011001000110010101011111011011100110111101110100011001000010111101110111011010000110000001110111011101010110010101110111011000110010110000100010011010000110000001110000011001010101111100100111011010010111110000100000011110000110001100100111011100100110010101110001000000110010010101100010011011101100000001100001011001010010000100010001001011000110000001101110110000000110110001111000011000010001011001111001001010010111111011000010011000000110001100100001000100000111111011001101010101010111100101001110101111000111110011000111010010011111000010110110000010110001000001010010110100111100110101001010110101110011110010100100110000011000111101111011011010000101100100111111000101111100010010110011101111011111100111011111001000100001111001011100100011101110011010101111100010000110010011000010100010011010000110111100001111111111011101011000000111100110101011001001101011010001101111010101001001101111000100010000101000000010010101101010001101101100100000111010000110100011111100000010000001101111011110001100000010110010001001111000010110001101111011000000000'
print(bool(a==finalbits))
return ie