I cannot read the generated qrcode when an embedded image is specified and error_correction is different from qrcode.constants.ERROR_CORRECT_H. I think this happens because the image obstructs a good portion of the qrcode and the error corrections smaller than ERROR_CORRECT_H are not enough to recover the information from this obstructed part.
You can try to scan the following images (the data on all of them is the URL https://brasil.io/ - check the code below). I was able to read only the last image (tried on Motorola Edge 20 Lite, Nothing phone/Android 14, iPhone SE iOS 17.4, Xiaomi Redmi 9 and Xiaomi Poco X3 Pro).
qrcode.constants.ERROR_CORRECT_L:
qrcode.constants.ERROR_CORRECT_M:
qrcode.constants.ERROR_CORRECT_Q:
qrcode.constants.ERROR_CORRECT_H:
Following is the code to generate the images above:
from urllib.request import urlopen
from pathlib import Path
import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import GappedSquareModuleDrawer, SquareModuleDrawer
# QRCode definitions
drawer = GappedSquareModuleDrawer()
eye_drawer = SquareModuleDrawer()
url = "https://brasil.io/"
center_image_url = "https://raw.githubusercontent.com/turicas/brasil.io/develop/branding/logo/logo-brasilio.png"
center_image_path = Path("logo-brasilio.png")
background_color = "white"
fill_color = "black"
if not center_image_path.exists():
print("Downloading center image")
response = urlopen(center_image_url)
with center_image_path.open(mode="wb") as fobj:
fobj.write(response.read())
# Test code
error_corrections = {
"L": qrcode.constants.ERROR_CORRECT_L,
"M": qrcode.constants.ERROR_CORRECT_M,
"Q": qrcode.constants.ERROR_CORRECT_Q,
"H": qrcode.constants.ERROR_CORRECT_H,
}
for error_correction, error_correction_constant in error_corrections.items():
print(f"Generating qrcode for error correction {error_correction}")
qr = qrcode.QRCode(
version=1,
error_correction=error_correction_constant,
box_size=10,
border=4,
)
qr.add_data(url)
qr.make(fit=True)
img = qr.make_image(
image_factory=StyledPilImage,
back_color=background_color,
embeded_image_path=str(center_image_path.absolute()),
fill_color=fill_color,
module_drawer=drawer,
eye_drawer=eye_drawer,
)
img.save(f"qrcode-brasilio-{error_correction}.png")
If I'm not doing anything wrong, then I'd suggest the best behaviour to be raising an exception if embeded_image_path is set and error_correction is different from qrcode.constants.ERROR_CORRECT_H. I'm willing to create a PR fixing this if you approve this fix idea.
I cannot read the generated qrcode when an embedded image is specified and
error_correction
is different fromqrcode.constants.ERROR_CORRECT_H
. I think this happens because the image obstructs a good portion of the qrcode and the error corrections smaller thanERROR_CORRECT_H
are not enough to recover the information from this obstructed part.You can try to scan the following images (the data on all of them is the URL
https://brasil.io/
- check the code below). I was able to read only the last image (tried on Motorola Edge 20 Lite, Nothing phone/Android 14, iPhone SE iOS 17.4, Xiaomi Redmi 9 and Xiaomi Poco X3 Pro).qrcode.constants.ERROR_CORRECT_L
:qrcode.constants.ERROR_CORRECT_M
:qrcode.constants.ERROR_CORRECT_Q
:qrcode.constants.ERROR_CORRECT_H
:Following is the code to generate the images above:
If I'm not doing anything wrong, then I'd suggest the best behaviour to be raising an exception if
embeded_image_path
is set anderror_correction
is different fromqrcode.constants.ERROR_CORRECT_H
. I'm willing to create a PR fixing this if you approve this fix idea.