lincolnloop / python-qrcode

Python QR Code image generator
https://pypi.python.org/pypi/qrcode
Other
4.35k stars 666 forks source link

Is there a way to feed in a list of lists that contain 1s and 0s and create the QR code from that instead of a string? #121

Closed ghost closed 3 years ago

ghost commented 7 years ago

I have some symbols created from another library (it allows structured append), and I simply want to use python-qrcode to generate the image. Is there a way I can give qrcode.QRCode my list of lists of 1s and 0s so that it will take the binary data and turn it into an image with the normal version, error correction, box size, and border arguments?

kuhne commented 7 years ago

You can try to set the module and module_count attributes of the QRCode. Untested code:

from qrcode import QRCode

qr = QRCode()
qr.modules = mylist
qr.modules_count = len(mylist)
qr.data_cache = True  # Necessary otherwise "modules" and "module_count" will be overridden
img = qr.make_image()

See https://github.com/lincolnloop/python-qrcode/blob/master/qrcode/main.py#L276 for the part where the image is generated and which attributes are involved.

ghost commented 7 years ago

Thanks, it worked like a charm! I really appreciate your help.

kuhne commented 7 years ago

Still ugly ;)

Other (maybe cleaner) options:

kuhne commented 7 years ago

I'd prefer the latter since it seems to belong to the public API while pyqrcode's _ prefix indicates a protected / private API which may change and the pyqrcode renderer functions take a different number of arguments. The renderers of segno.writers seem to take (at a first glance) the same number of arguments.

kuhne commented 7 years ago

segno is picky regarding the QR code version. I thought about

from segno import writers
import io
out = BytesIO()
mylist = [[1, 0, 0, 0, 1], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]]
writers.write_png(mylist, 1, out=out, scale=10)  # Use 1 as QFR code version constant

but it doesn't render the expected image. But I discovered the save function

from segno import writers
import io
out = BytesIO()
writers.save(mylist, qrcode_version, kind='png', out=out, scale=10)
out = BytesIO()
writers.save(mylist, qrcode_version, kind='svg', out=out, scale=10)

should work... You're independent of a concrete rendering function as long as you provide the "kind" parameter

ghost commented 7 years ago

I really like the segno writers method. Unfortunately I keep running into the problem where my QR reader (QuickMark) fails anytime the combined text is roughly 2691 characters long. I'm generating 4 QR codes with the structured append feature of libqrencode, but after QuickMark reads each it shows an empty box instead of the combined text string. If I only encode 2690 characters, it correctly combines the symbols and creates the correct text string. I'm assuming this is all the fault of QuickMark, but I'm not 100% sure. And I can't find another QR reader that supports structured append.

ghost commented 7 years ago

Oddly enough, I can make a string of 4000 "A"s and the app works fine appending the data from the 4 QR codes and displaying it in the app. I'm ultimately trying to encode a json string, so I'm wondering if there's something uniquely different about json strings that is causing the problem.

ghost commented 7 years ago

After further testing, I'm a bit closer to the problem. When you have 2 or more QR codes that are appended, if any of the QR codes have 8 numbers in a row encoded in them, the app displays a blank result. Right now my json string has the date as "20161011" and that's causing the issue. I even tested "00000001", "10000000", and a few others and confirmed the problem. The only way to have 8 or more numbers is if they're all the same number (such as "00000000").

I'm not sure if this problem is resulting from how libqrencode is encoding the data into the symbols or from a bug in QuickMark.