I have a problem reading qrcode data from image (not using webcam just get qrcode.png and read it) I'm using pyqrcode module to generate my qrcodes and it works well and when I read it using any mobile phone built in reader it gives me correct data without any problems but when I try to read it using python the output is always "[]" empty bracket so where's the problem
print(data)
dest = str(data)
myQR = QRCode(dest, encoding = 'utf-8')
myQR.show()
myQR.png('QR.png', scale=8)
this how i create qrcode and i prefer not using (cv2 or zbar) cuz I have problem downloading zbar
edit
built in readers in mobile phones reads it correctly without any errors and gives me correct data
Related
I'm a beginner in python and I'm trying to send someone my small python program together with a picture that'll display when the code is run.
I tried to first convert the image to a binary file thinking that I'd be able to paste it in the source code but I'm not sure if that's even possible as I failed to successfully do it.
You can base64-encode your JPEG/PNG image which will make it into a regular (non-binary string) like this:
base64 -w0 IMAGE.JPG
Then you want to get the result into a Python variable, so repeat the command but copy the output to your clipboard:
base64 -w0 IMAGE.JPG | xclip -selection clipboard # Linux
base64 -w0 IMAGE.JPG | pbcopy # macOS
Now start Python and make a variable called img and paste the clipboard into it:
img = 'PASTE'
It will look like this:
img = '/9j/4AAQSk...' # if your image was JPEG
img = 'iVBORw0KGg...' # if your image was PNG
Now do some imports:
from PIL import Image
import base64
import io
# Make PIL Image from base64 string
pilImage = Image.open(io.BytesIO(base64.b64decode(img)))
Now you can do what you like with your image:
# Print its description and size
print(pilImage)
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=200x100>
# Save it to local disk
pilImage.save('result.jpg')
You can save a picture in byte format inside a variable in your program. You can then convert the bytes back into a file-like object using the BytesIO function of the io module and plot that object using the Image module from the Pillow library.
import io
import PIL.Image
with open("filename.png", "rb") as file:
img_binary = file.read()
img = PIL.Image.open(io.BytesIO(img_binary))
img.show()
To save the binary data inside your program without having to read from the source file you need to encode it with something like base64, use print() and then simply copy the output into a new variable and remove the file reading operation from your code.
That would look like this:
img_encoded = base64.encodebytes(img_binary)
print(img_binary)
img_encoded = " " # paste the output from the console into the variable
the output will be very long, especially if you are using a big image. I only used a very small png for testing.
This is how the program should look like at the end:
import io
import base64
import PIL.Image
# with open("filename.png", "rb") as file:
# img_binary = file.read()
# img_encoded = base64.encodebytes(img_binary)
img_encoded = b'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABX[...]'
img = PIL.Image.open(io.BytesIO(base64.decodebytes(img_encoded)))
img.show()
You could perhaps have your Python program download the image from a site where you upload files such as Google Drive, Mega, or Imgur. That way, you can always access and view the image easily without the need of running the program or for example converting the binary back into the image in the method you mentioned.
Otherwise, you could always store the image as bytes in a variable and have your program read this variable. I'm assuming that you really wish to do it this way as it would be easier to distribute as there is only one file that needs to be downloaded and run.
Or you could take a look at pyinstaller which is made for python programs to be easily distributed across machines without the need to install Python by packaging it as an executable (.exe) file! That way you can include the image file together by embedding it into the program. There are plenty of tutorials for pyinstaller you could google up. Note: Include the '--onefile' in your parameters when running pyinstaller as this will package the executable into a single file that the person you're sending it to can easily open whoever it may be-- granted the executable file can run on the user's operating system. :)
I've tried this a number of ways and have searched high and low, but no matter what I try (including all posts I could find here on the subject) I can't manage to convert my base64 string of an HTML document / canvas containing JavaScript.
I'm not getting the incorrect padding error which is quite common (I have ensured 'data:text/html;base64,' is not included at the start of the base64 string.)
I have also checked the base64 string both by checking and running the original .html file, which renders in browser with no issue, and decoding the string with an online decoder.
I know I must be missing something very simple here, but after several hours I'm ready to pull my hair out.
My encoding step is as follows:
htmlSource = bytes(htmlSource,'UTF-8')
fullBase64 = base64.b64encode(htmlSource)
The resultant base64 string is included in my attempts below, which should generate a turquoise oval with shadow on a dirty white background in 4k.
The following attempts all create a png file, only 1kb in size, which cannot be opened - 'It may be damaged or use a file format that Preview doesn’t recognise.':
import base64
img_data = b'PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgbmFtZT0ndmlld3BvcnQnIGNvbnRlbnQ9J3dpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAnPgogIDwvaGVhZD4KPGJvZHk+CjxzdHlsZT4KICAgIGJvZHksIGh0bWwgewogICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7CiAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50OwogICAgICBtYXJnaW46IDA7CiAgICB9CiAgICAqIHsKICAgICAgcGFkZGluZzogMDsKICAgICAgbWFyZ2luOiAwOwogICAgfQo8L3N0eWxlPgoKPGNhbnZhcyBpZD0nbXlDYW52YXMnIHN0eWxlPSdvYmplY3QtZml0OiBjb250YWluOyB3aWR0aDogOTl2dzsgaGVpZ2h0OiA5OXZoOyc+CllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBIVE1MNSBjYW52YXMgdGFnLjwvY2FudmFzPgoKPHNjcmlwdD4KdmFyIGNhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdteUNhbnZhcycpOwpjYW52YXMud2lkdGggPSA0MDk2OwpjYW52YXMuaGVpZ2h0ID0gNDA5NjsKY2FudmFzLnN0eWxlLndpZHRoID0gJzk5dncnOwpjYW52YXMuc3R5bGUuaGVpZ2h0ID0gJzk5dmgnOwp2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7CnZhciBjYW52YXNXID0gY3R4LmNhbnZhcy53aWR0aDsKdmFyIGNhbnZhc0ggPSBjdHguY2FudmFzLmhlaWdodDsKCmN0eC5maWxsU3R5bGUgPSAncmdiYSgyMDAsIDE5NywgMTc3LCAxKSc7CmN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXNXLCBjYW52YXNIKTsKCmN0eC5zaGFkb3dCbHVyID0gY2FudmFzVzsKY3R4LnNoYWRvd0NvbG9yID0gJ3JnYmEoMCwgMCwgMCwgMC4zKSc7CmN0eC5iZWdpblBhdGgoKTsKY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDUxLCAyMjAsIDE5MSwgMSknOwpjdHguZWxsaXBzZShjYW52YXNXIC8gMiwgY2FudmFzSCAvIDIgLCBjYW52YXNXICogLjQsIGNhbnZhc0ggKiAuNDUsIDAsIDAsIDIgKiBNYXRoLlBJKTsKY3R4LmZpbGwoKTsKCgoKPC9zY3JpcHQ+Cgo8L2JvZHk+CjwvaHRtbD4='
with open("turquoise egg.png", "wb") as fh:
fh.write(base64.decodebytes(img_data))
Version 2
from binascii import a2b_base64
data = 'PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgbmFtZT0ndmlld3BvcnQnIGNvbnRlbnQ9J3dpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAnPgogIDwvaGVhZD4KPGJvZHk+CjxzdHlsZT4KICAgIGJvZHksIGh0bWwgewogICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7CiAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50OwogICAgICBtYXJnaW46IDA7CiAgICB9CiAgICAqIHsKICAgICAgcGFkZGluZzogMDsKICAgICAgbWFyZ2luOiAwOwogICAgfQo8L3N0eWxlPgoKPGNhbnZhcyBpZD0nbXlDYW52YXMnIHN0eWxlPSdvYmplY3QtZml0OiBjb250YWluOyB3aWR0aDogOTl2dzsgaGVpZ2h0OiA5OXZoOyc+CllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBIVE1MNSBjYW52YXMgdGFnLjwvY2FudmFzPgoKPHNjcmlwdD4KdmFyIGNhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdteUNhbnZhcycpOwpjYW52YXMud2lkdGggPSA0MDk2OwpjYW52YXMuaGVpZ2h0ID0gNDA5NjsKY2FudmFzLnN0eWxlLndpZHRoID0gJzk5dncnOwpjYW52YXMuc3R5bGUuaGVpZ2h0ID0gJzk5dmgnOwp2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7CnZhciBjYW52YXNXID0gY3R4LmNhbnZhcy53aWR0aDsKdmFyIGNhbnZhc0ggPSBjdHguY2FudmFzLmhlaWdodDsKCmN0eC5maWxsU3R5bGUgPSAncmdiYSgyMDAsIDE5NywgMTc3LCAxKSc7CmN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXNXLCBjYW52YXNIKTsKCmN0eC5zaGFkb3dCbHVyID0gY2FudmFzVzsKY3R4LnNoYWRvd0NvbG9yID0gJ3JnYmEoMCwgMCwgMCwgMC4zKSc7CmN0eC5iZWdpblBhdGgoKTsKY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDUxLCAyMjAsIDE5MSwgMSknOwpjdHguZWxsaXBzZShjYW52YXNXIC8gMiwgY2FudmFzSCAvIDIgLCBjYW52YXNXICogLjQsIGNhbnZhc0ggKiAuNDUsIDAsIDAsIDIgKiBNYXRoLlBJKTsKY3R4LmZpbGwoKTsKCgoKPC9zY3JpcHQ+Cgo8L2JvZHk+CjwvaHRtbD4='
binary_data = a2b_base64(data)
fd = open('turquoise egg.png', 'wb')
fd.write(binary_data)
fd.close()
Version 3
import base64
fileString = 'PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgbmFtZT0ndmlld3BvcnQnIGNvbnRlbnQ9J3dpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAnPgogIDwvaGVhZD4KPGJvZHk+CjxzdHlsZT4KICAgIGJvZHksIGh0bWwgewogICAgICBwYWRkaW5nOiAwICFpbXBvcnRhbnQ7CiAgICAgIG1hcmdpbjogMCAhaW1wb3J0YW50OwogICAgICBtYXJnaW46IDA7CiAgICB9CiAgICAqIHsKICAgICAgcGFkZGluZzogMDsKICAgICAgbWFyZ2luOiAwOwogICAgfQo8L3N0eWxlPgoKPGNhbnZhcyBpZD0nbXlDYW52YXMnIHN0eWxlPSdvYmplY3QtZml0OiBjb250YWluOyB3aWR0aDogOTl2dzsgaGVpZ2h0OiA5OXZoOyc+CllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBIVE1MNSBjYW52YXMgdGFnLjwvY2FudmFzPgoKPHNjcmlwdD4KdmFyIGNhbnZhcyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdteUNhbnZhcycpOwpjYW52YXMud2lkdGggPSA0MDk2OwpjYW52YXMuaGVpZ2h0ID0gNDA5NjsKY2FudmFzLnN0eWxlLndpZHRoID0gJzk5dncnOwpjYW52YXMuc3R5bGUuaGVpZ2h0ID0gJzk5dmgnOwp2YXIgY3R4ID0gY2FudmFzLmdldENvbnRleHQoJzJkJyk7CnZhciBjYW52YXNXID0gY3R4LmNhbnZhcy53aWR0aDsKdmFyIGNhbnZhc0ggPSBjdHguY2FudmFzLmhlaWdodDsKCmN0eC5maWxsU3R5bGUgPSAncmdiYSgyMDAsIDE5NywgMTc3LCAxKSc7CmN0eC5maWxsUmVjdCgwLCAwLCBjYW52YXNXLCBjYW52YXNIKTsKCmN0eC5zaGFkb3dCbHVyID0gY2FudmFzVzsKY3R4LnNoYWRvd0NvbG9yID0gJ3JnYmEoMCwgMCwgMCwgMC4zKSc7CmN0eC5iZWdpblBhdGgoKTsKY3R4LmZpbGxTdHlsZSA9ICdyZ2JhKDUxLCAyMjAsIDE5MSwgMSknOwpjdHguZWxsaXBzZShjYW52YXNXIC8gMiwgY2FudmFzSCAvIDIgLCBjYW52YXNXICogLjQsIGNhbnZhc0ggKiAuNDUsIDAsIDAsIDIgKiBNYXRoLlBJKTsKY3R4LmZpbGwoKTsKCgoKPC9zY3JpcHQ+Cgo8L2JvZHk+CjwvaHRtbD4='
decodeit = open('turquoise egg.png', 'wb')
decodeit.write(base64.b64decode((fileString)))
decodeit.close()
FWIW I originally used the following code to create a png from the HTML without using base64, but it would only ever save the first element of JavaScript generated on the canvas (ie the background) and since I require the information in base64 anyway, thought I would approach it this way in order to capture the complete image
file = open('html.html', 'r')
imgkit.from_file(file, 'png.png')
file.close()
Html2Image has provided the solution I was looking for.
Whilst imgkt wasn't saving the fully rendered canvas, taking screenshot with html2canvas does. Documentation is here and I implemented as follows:
from html2image import Html2Image
hti.screenshot(
html_file = ‘html.html’,
size = (imageW, imageH),
save_as = ‘png.png'
)
I'm trying to successfully decode Data Matrix barcodes that are base256 encoded using pylibdmtx. When the barcode contains a 0x00 byte the library seems to treat it as a string terminator (null) and ignores the rest of the data in the barcode.
Here is a snippet of code that will create a barcode and decode it:
from pylibdmtx.pylibdmtx import encode, decode
from PIL import Image
message = b'\x16\x05abc\x64\x00\x65\x66g'
print('message:',message)
barcode = encode(message)
img = Image.frombytes('RGB', (barcode.width, barcode.height), barcode.pixels)
# uncomment if you want to save the barcode to a file
#img.save('barcode.png')
decoded = decode(img)
print('decoded:',decoded)
print(' length:',len(decoded[0].data))
Here is the result:
message: b'\x16\x05abcd\x00efg'
decoded: [Decoded(data=b'\x16\x05abcd', rect=Rect(left=9, top=10, width=80, height=79))]
length: 6
The created barcode reads properly with other online tools and dmtxread invoked from a command line.
Is there a limitation with the python wrappers for libdmtx or something I am doing wrong?
Other Info:
This is the simplest example I could come up with to illustrate the problem. The barcodes are much larger and already in production systems.
I did try the python wrappers for the ZXing library and it did not even recognize many of the barcodes. I am open to using other libraries.
Thank you.
I'm writing Python program that does the following:
Create a QR code > Save to a png file > Open the file > Read the QR code information
However, when the data on the code has special characters, I got some confusion output data. Here's my code:
import pyqrcode
from PIL import Image
from pyzbar.pyzbar import decode
data = 'Thomsôn Gonçalves Ámaral,325.432.123-21'
file_iso = 'QR_ISO.png'
file_utf = 'QR_Utf.png'
#creating QR codes
qr_iso = pyqrcode.create(data) #creates qr code using iso-8859-1 encoding
qr_utf = pyqrcode.create(data, encoding = 'utf-8') #creates qr code using utf-8 encoding
#saving png files
qr_iso.png(file_iso, scale = 8)
qr_utf.png(file_utf, scale = 8)
#Reading and Identifying QR codes
img_iso = Image.open(file_iso)
img_utf = Image.open(file_utf)
dec_iso = decode(img_iso)
dec_utf = decode(img_utf)
# Reading Results:
print(dec_iso[0].data)
print(dec_iso[0].data.decode('utf-8'))
print(dec_iso[0].data.decode('iso-8859-1'),'\n')
print(dec_utf[0].data)
print(dec_utf[0].data.decode('utf-8'))
print(dec_utf[0].data.decode('iso-8859-1'))
And here's the output:
b'Thoms\xee\x8c\x9e Gon\xe8\xbb\x8blves \xef\xbe\x81maral,325.432.123-21'
Thoms Gon軋lves チmaral,325.432.123-21
Thoms Gon軋lves ï¾maral,325.432.123-21
b'Thoms\xef\xbe\x83\xef\xbd\xb4n Gon\xef\xbe\x83\xef\xbd\xa7alves \xef\xbe\x83\xef\xbc\xbbaral,325.432.123-21'
Thomsテエn Gonテァalves テ[aral,325.432.123-21
Thomsテエn Gonテァalves テ[aral,325.432.123-21
For simple data it works just fine, but when data has characters like 'Á, ç ' and so on this happens.
Any ideas of what should I do to fix it?
Additional information:
I'm using python 3.8 and PyCharm IDE
When I scan the generated codes using an Android App, it reads both codes just fine.
I've read this topic: Unicode Encoding and decoding issues in QRCode but it didn't help much
Try to encode the UTF-8 decoded result with shift-jis and decode the result again with UTF-8.
dec_utf[0].data.decode('utf-8').encode('shift-jis').decode('utf-8')
This works at least with your example where the QR code uses UTF-8 as well.
See also https://github.com/NaturalHistoryMuseum/pyzbar/issues/14
Alright! Got some updates:
Short version:
The answer from #user14091216 seems to solve the problem. The line:
dec_utf[0].data.decode('utf-8').encode('shift-jis').decode('utf-8')
does a double-decoding, which fix the problem. I did lots of tests without any error. The new code is down bellow.
What I've tried and found out - Long version:
After talking to some colleagues they suggested that my data was somehow double-encoded. I still don't know why this happens, but for what I've read, it seems to be a problem with pyzbar lib, when it reads data with special characters.
The first thing I've tried was to use the BOM (byte order mark):
Based on my original code, used this lines:
data = '\xEF\xBB\xBF' + 'Thomsôn Gonçalves Ámaral,325.432.123-21'
qr_iso = pyqrcode.create(data) #creates qr code using iso-8859-1 encoding as standard
qr_iso.png(file_iso, scale = 8)
img_iso = Image.open(file_iso)
dec_iso = decode(img_iso)
print(dec_iso[0].data.decode('utf-8'))
And this was the output:
Thomsôn Gonçalves Ámaral,325.432.123-21
Note that even though I created the QR code using 'iso-8859-1' enconding, it only worked when decoded as 'utf-8'.
I also need to treat this data, removing the BOM. Which is easy, but it is an additional step. It worth mentioning that for simpler data (without the special characters), the output didn't have the '' with it.
The solution above works, but at least for me it didn't seem completely right. I was using because I didn't have a better one.
I even try to double decode the data:
Based on 'python double-decoding' searches, I've tried codes like this (and some variations):
dec_iso[0].data.decode('iso-8859-1').encode('raw_unicode_escape').decode('iso-8859-1')
dec_utf[0].data.decode('utf-8).encode('raw_unicode_escape').decode('utf-8)
but none of this worked.
The fix:
As suggested, I tried the following line:
dec_utf[0].data.decode('utf-8').encode('shift-jis').decode('utf-8')
And it worked perfectly. I've tested it with over 1800 data strings without getting a single error.
The QR code generation seems to be fine. This line of code only treats the output data from the pyzbar lib, when it reads the QR image (and it doesn't need to be a QR code created by pyqrcode lib specifically).
I haven't been able to decode QR codes generated with 'iso-8859-1' encoding using the same technique. I might be something related to pyzbar or I simply haven't found out which one is the right pattern for the decode-encode-decode process.
So here's a simple code for creating and reading a QR code, based on utf-8 encoding:
import pyqrcode
from PIL import Image
from pyzbar.pyzbar import decode
data = 'Thomsôn Gonçalves Ámaral,325.432.123-21'
file_utf = 'QR_Utf.png'
#creating QR codes
qr_utf = pyqrcode.create(data, encoding = 'utf-8') #creates qr code using utf-8 encoding
#saving png file
qr_utf.png(file_utf, scale = 8)
#Reading and Identifying QR code
img_utf = Image.open(file_utf)
dec_utf = decode(img_utf)
# Decoding Results:
print(dec_utf[0].data.decode('utf-8').encode('shift-jis').decode('utf-8'))
For more info, see also:
iOS: ZBar SDK unicode characters
https://sourceforge.net/p/zbar/support-requests/21/
I have created a binary file of an image using the code:
f1=open('file_name.png','rb')
f2=open('newfile.txt ','wb')
byte=f1.read()
f2.write(byte)
I have got the binary file but now I want to load that image using that binary code. Now, I want to load that image (or maybe recreate) that image by the source code itself in other file. how do I do that?
please note: I'm a newbie at python.
I have looked over the Various and found programs that I didn't understand.
this code was present there most of the time I searched. It made a bit sense to me.
I have tried the code with base64:
import base64
with open("t.png", "rb") as imageFile:
str = base64.b64encode(imageFile.read())
print (str)
but this is not doing anything. not showing errors, not printing the string either.
if there is a simple way please I request you to explain by the code.
Thanks in advance!