-
Notifications
You must be signed in to change notification settings - Fork 727
Description
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.