如何用Python生成带圆点与圆形定位标记的二维码?
自定义样式二维码实现方案
需求说明
- 已通过Python
qrcode库实现圆形点阵二维码,但无法生成圆形定位标记,也无法设置圆点间的间距 - 可接受使用其他Python库实现目标样式(参考下方示例图)
现有实现代码
import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.moduledrawers.pil import CircleModuleDrawer qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L) qr.add_data('Some data') img_0 = qr.make_image(image_factory=StyledPilImage, module_drawer=CircleModuleDrawer()) img_0.save("img0.png")
目标样式参考

解决方案
方案1:使用segno库(推荐,配置更便捷)
segno库原生支持自定义模块样式、定位标记样式及模块间距,无需复杂自定义类。
- 安装依赖
pip install segno
- 实现代码
import segno # 生成基础二维码(纠错等级L) qr = segno.make('Some data', error='L') # 保存为自定义样式二维码 qr.save( 'custom_qr.png', kind='png', module_drawer='circle', # 设置点阵为圆形 finder_drawer='circle', # 设置定位标记为圆形 module_gap=1, # 圆点间的间距(单位:像素,可按需调整) scale=10, # 缩放比例,控制二维码大小 border=4, # 空白边框宽度(符合QR码标准) module_color='#000000', # 圆点颜色 background='white' # 背景颜色 )
方案2:基于qrcode库自定义实现
通过继承重写类,实现圆形定位标记和圆点间距调整。
import qrcode from qrcode.image.styledpil import StyledPilImage from qrcode.image.styles.moduledrawers.pil import CircleModuleDrawer from PIL import ImageDraw # 自定义定位标记绘制类:替换默认方形为圆形 class CustomFinderImage(StyledPilImage): def draw_finder_pattern(self, draw: ImageDraw, box, size): center_x = box[0] + size // 2 center_y = box[1] + size // 2 # 外层大圆 draw.ellipse([box[0], box[1], box[0]+size, box[1]+size], fill=self.fill_color) # 中间空白圆 inner_size = int(size * 0.6) draw.ellipse([ center_x - inner_size//2, center_y - inner_size//2, center_x + inner_size//2, center_y + inner_size//2 ], fill=self.background_color) # 内层小圆 inner_inner_size = int(size * 0.3) draw.ellipse([ center_x - inner_inner_size//2, center_y - inner_inner_size//2, center_x + inner_inner_size//2, center_y + inner_inner_size//2 ], fill=self.fill_color) # 自定义圆点绘制类:缩小圆点尺寸实现间距 class SpacedCircleDrawer(CircleModuleDrawer): def drawrect(self, box, ctx): box_size = box[2] - box[0] gap_ratio = 0.2 # 间距占模块尺寸的比例,可调整 gap = int(box_size * gap_ratio) # 计算缩小后的圆点位置 new_box = [ box[0] + gap//2, box[1] + gap//2, box[2] - gap//2, box[3] - gap//2 ] ctx.ellipse(new_box, fill=self.fill_color) # 生成并保存二维码 qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L) qr.add_data('Some data') custom_img = qr.make_image( image_factory=CustomFinderImage, module_drawer=SpacedCircleDrawer(), fill_color='#000000', background_color='white' ) custom_img.save("custom_qrcode.png")
内容的提问来源于stack exchange,提问作者Massimo Manca
相关产品推荐
相关产品推荐

