I'm trying to decode a QR Code using Python, or any other language to be honest. I am also familiar with Javascript or PHP, but Python seemed to be the most appropriate one for this task.
This is part of a bigger piece of code that I am writing for a little challenge. I need to extract a password from the QR Code. I've tried using a QR Code reader on my phone and I can get the password so I can confirm that there is no issue with the QR Code itself.
Here is the QRCode:
And the string to retrieve is "The key is /qrcod_OMevpf".
So far I've tried using two different python libraries. Open CV and Pyzbar, with the following codes:
OpenCV
image = cv2.imread(imgAbsolutePath)
qrCodeDetector = cv2.QRCodeDetector()
decodedText, points, _ = qrCodeDetector.detectAndDecode(image)
if points is not None:
# QR Code detected handling code
print("QR code detected")
print(decodedText)
else:
print("QR code not detected")
Which prints "QR code detected" and then an empty string.
Pyzbar
qr = decode(Image.open('result.png'), symbols=[ZBarSymbol.QRCODE])
print(qr)
Which prints "[]"
Do you know why these don't work or can you suggest any other libraries that works ?
Thanks
I finally got it to work using zxing :
from zxing import BarCodeReader
def decode_qr_code(image_path):
reader = BarCodeReader()
barcode = reader.decode(image_path)
return barcode.parsed
qr_code = decode_qr_code("result.png")
print(qr_code)
Related
I have created a session and located the QR code element ID using endpoint mentioned in Appium documentation.
This is the value of text I'm getting from QR code; I expect the actual decode of QR code which can be further used in applications for automation. I was wondering if other application needs to be used or it is possible in postman itself.
The issue was solved by using python's cv2 library
filename = "img.png"
# read the QRCODE image
image = cv2.imread(filename)
# initialize the cv2 QRCode detector
detector = cv2.QRCodeDetector()
# detect and decode
data, vertices_array, binary_qrcode = detector.detectAndDecode(image)
if vertices_array is not None:
print("QRCode data:")
print(data)
else:
print("There was some error")
Well, in fact, there are several questions here, is the QR code value static or dynamic, that is, does the QR code change during each test or can you use the same QR for all tests
If the value does not change(static), you can create a file, say .yaml, in the resources or test data directory, where your value will be stored in an encoded form, then you read this value from the file, decode it and pass it to the test script
If the QR code changes(dynamic value) for each test, you can create an API call, for python you can use the requests library or Java RestAssured, you take the encoded value from the response, decode it and pass it to the test script
the implementation depends on the above, but the whole process must be implemented within your framework
So you don't need to use additional tools like Postman etc to get value and decode it, if you want to automate your case properly combine API and UI
To decode value in Python I use Fernet, Java bouncycastle
I have been working on this code for a project at work which will (hopefully) take in images from a scanning electron microscope and generate 3D STL files of the structures were imaging. I'm at the stage with the code where I'm trying to generate a 3D structure from a 'coloured in' binary image I've made with some edge detection code I wrote. I came across this post How can i extrude a stl with python that basically does exactly what I need (generating a meshed 3D structure from a binary image). I've tried using/adapting the code in the answer to that post (see below) but I keep running into the following error: polyline2 = mr.distanceMapTo2DIsoPolyline(dm.value(), isoValue=127) RuntimeError: Bad expected access. I cant find anything online about why this is happening and I'm no expert in Python so have no idea myself. If anyone has an idea, I'd really appreciate it!
Code from answer to above post:
import meshlib.mrmeshpy as mr
# load image as Distance Map object:
dm = mr.loadDistanceMapFromImage(mr.Path("your-image.png"), 0)
# find boundary contour of the letter:
polyline2 = mr.distanceMapTo2DIsoPolyline(dm.value(), isoValue=127)
# triangulate the contour
mesh = mr.triangulateContours(polyline2.contours2())
# extrude itself:
mr.addBaseToPlanarMesh(mesh, zOffset=30)
# export the result:
mr.saveMesh(mesh, mr.Path("output-mesh.stl"))
I have tried the following:
Reconfigured the MeshLib package that this command uses. Package docs here: https://meshinspector.github.io/MeshLib/html/index.html#PythonIntegration
Updating VS studio/python/MeshLib
In older version of meshlib python module RuntimeError: Bad expected access indicated that mr.loadDistanceMapFromImage had failed, you should had checked it like this:
import meshlib.mrmeshpy as mr
# load image as Distance Map object:
dm = mr.loadDistanceMapFromImage(mr.Path("your-image.png"), 0)
# check dm
if ( not dm.has_value() ):
raise Exception(dm.error())
# find boundary contour of the letter:
polyline2 = mr.distanceMapTo2DIsoPolyline(dm.value(), isoValue=127)
# triangulate the contour
mesh = mr.triangulateContours(polyline2.contours2())
# extrude itself:
mr.addBaseToPlanarMesh(mesh, zOffset=30)
# export the result:
mr.saveMesh(mesh, mr.Path("output-mesh.stl"))
But in actual release your code will rise exception with real error.
Please make sure that path is correct, if it doesn't help please provide more info like png file and version of python and version of MeshLib and anything else you find related.
P.S. If there is real problem with MeshLib better open issue in github.
I have a library of hundreds of pictures from which I need to extract information encoded in a QR code in each picture.
For 70% of the pictures, pyzbar simply works. For more difficult cases, I try non-linear binarization of the image as suggested by this post: https://stackoverflow.com/a/61443430/1579211
This gets me another 15-20% of the way.
But for about 10% of the images this fails:
from PIL import Image
from pyzbar.pyzbar import decode, ZBarSymbol
from kraken.binarization import nlbin
def read_QRcode(image):
codes = decode(image, symbols=[ZBarSymbol.QRCODE])
if not codes:
codes = decode(nlbin(image), symbols=[ZBarSymbol.QRCODE])
if not codes:
raise RuntimeError(
f'Could not decode a QR code from {image.filename}...'
)
return codes
image = Image.open('sample.jpg')
read_QRcode(image)
When I open up these images (attached sample.jpg) on the screen, my phone, which has a QR scanner built into the camera app, can decode this QR code correctly (see attached screenshot or try yourself).
Does anyone feel up-to the challenge to help me figure this out?
I encoded the number 1639 in the two QR codes of the image below (downloadable here). I printed it, took a photo and tried to detect it:
import zbar
from PIL import Image
scanner = zbar.ImageScanner()
pil = Image.open('20180520_170027_2.jpg').convert('L')
width, height = pil.size
raw = pil.tobytes()
image = zbar.Image(width, height, 'Y800', raw)
result = scanner.scan(image)
for symbol in image:
print symbol.data.decode(u'utf-8') # 1639
It works, even if the size of the QR code is small (~1x1 cm), which is great!
Question: how to get the x, y position of the corners of the QR codes?
It's sure that zbar has this information internally (mandatory to be able to decode the QR code!), but how to get access to it?
Note: here is how to install zbar on Windows and Python 2.7
As suggested by a hint in a comment,
print(symbol.location)
gives the coordinates.
It looks like the zbar::Symbol class in the C++ docs of zlib has the methods get_location_x(), get_location_y() and get_location_size(), so your intuition that this data exists underneath was right.
Coming back to Python, when reading the documentation of the zbar Python binding, it looks like a position field is available to get the location of the QR code:
import zbar
image = read_image_into_numpy_array(...) # whatever function you use to read an image file into a numpy array
scanner = zbar.Scanner()
results = scanner.scan(image)
for result in results:
print(result.type, result.data, result.quality, result.position)
The size of the QR code is probably also available as a field in result (e.g. result.size), and you can use it to find the 3 other corners.
On my Ubuntu server I've installed the python-qrtools package (which makes use of zbar) using sudo apt-get install python-qrtools to decode images of QR-codes and bar-codes in Python like this:
>>> qr = qrtools.QR()
>>> qr.decode('the_qrcode_or_barcode_image.jpg')
True
>>> print qr.data
Hello! :)
This works perfectly fine.
I now want to store this data and regenerate the image at a later point in time. But the problem is that I don't know whether the original image was a QR-code or some type of bar-code. I checked all properties of the qr object, but none of them seems to give me the type of Encoding Style (QR/bar/other).
In this SO thread it is described that ZBar does give back the type of Encoding Style, but it only gives an example in Objective-C, plus I'm not sure if this is actually an answer to what I am looking for.
Does anybody know how I can find out the type of Encoding Style (so QR-code/BAR-code/other) in Python (preferably using the python-qrtools package)? And if not in Python, are there any Linux command line tools which can find this out? All tips are welcome!
Looking at the source of qrtools, I cannot see any way to get the type but there is a zbar python lib, based on the scan_image example, the code below seems to do what you want:
import zbar
import Image
scanner = zbar.ImageScanner()
scanner.parse_config('enable')
img = Image.open("br.png").convert('L')
width, height = img.size
stream = zbar.Image(width, height, 'Y800', img.tostring())
scanner.scan(stream)
for symbol in stream:
print 'decoded', symbol.type, 'symbol', '"%s"' % symbol.data
Using a random barcode I grabbed from the net:
decoded UPCA symbol "123456789012"
Using this qr code outputs:
decoded QRCODE symbol "http://www.reichmann-racing.de"