Python QR Code 艺术二维码生成项目如何优化与使用

最近打算做一个和二维码相关的项目,搜了一下相关资料,发现了一个Python 生成艺术二维码的项目,挺有意思的,顺手就改了下,把它做成 http 服务。

项目原作者是 [@sylnsfar](/user/sylnsfar),这里是他两年前发的主题。

改的过程中发现,原项目生成的二维码背景图清晰度不够,能明显看到马赛克:

所以又研究了下作者提到的Halftone QR Code,发现其实可以直接生成一个透明背景的二维码,把背景的填充的工作交给使用者。于是动手改起来,把项目改成了一个生成透明背景二维码的 http 服务器,发现效果挺不错的。

实际效果测试

生成的透明背景二维码:

自行使用 PS 叠加背景图,支持任意高清图,无马赛克:

甚至制作海报:

因为原项目使用 GPLv3 协议,所以我修改之后的项目也使用 GPLv3 进行开源: https://github.com/tiaod/qrcode-art-server


Python QR Code 艺术二维码生成项目如何优化与使用

17 回复

赞一个


这个项目核心是使用qrcodePIL库,通过控制模块颜色和嵌入图片来生成艺术二维码。关键优化点在于平衡艺术性和可读性。

1. 基础生成与优化 直接使用qrcode生成,通过fill_colorback_color控制主色调。

import qrcode

qr = qrcode.QRCode(
    version=7,  # 控制尺寸和容量,1-40
    error_correction=qrcode.constants.ERROR_CORRECT_H,  # 最高容错率30%
    box_size=10,
    border=4,
)
qr.add_data("https://your.link")
qr.make(fit=True)

img = qr.make_image(fill_color="#E34F51", back_color="white")
img.save("basic_qr.png")

2. 嵌入Logo(保持可扫描性) 关键是将Logo尺寸控制在二维码面积的30%以内,并确保对比度。

from PIL import Image

def add_logo(qr_img, logo_path, size_ratio=0.2):
    qr = qr_img.convert("RGBA")
    logo = Image.open(logo_path).convert("RGBA")
    
    # 计算Logo尺寸
    qr_width, qr_height = qr.size
    logo_size = int(qr_width * size_ratio)
    
    # 等比例缩放Logo
    logo.thumbnail((logo_size, logo_size), Image.Resampling.LANCZOS)
    
    # 居中粘贴
    pos = ((qr_width - logo.size[0]) // 2, (qr_height - logo.size[1]) // 2)
    qr.paste(logo, pos, logo)  # 使用alpha通道作为掩码
    return qr

art_qr = add_logo(img, "logo.png")
art_qr.save("qr_with_logo.png")

3. 高级艺术化(渐变/形状) 通过遍历每个模块像素来实现自定义绘制逻辑。

def gradient_qr(data, colors):
    qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H)
    qr.add_data(data)
    qr.make()
    
    matrix = qr.get_matrix()
    size = len(matrix)
    img = Image.new("RGB", (size*10, size*10), "white")
    draw = ImageDraw.Draw(img)
    
    for y in range(size):
        for x in range(size):
            if matrix[y][x]:
                # 简单线性渐变示例
                ratio = y / size
                r = int(colors[0][0] * (1-ratio) + colors[1][0] * ratio)
                g = int(colors[0][1] * (1-ratio) + colors[1][1] * ratio)
                b = int(colors[0][2] * (1-ratio) + colors[1][2] * ratio)
                draw.rectangle(
                    [x*10, y*10, (x+1)*10, (y+1)*10],
                    fill=(r, g, b)
                )
    return img

gradient_qr("Hello", [(255,0,0), (0,0,255)]).save("gradient_qr.png")

使用建议: 始终用真机多角度测试可扫描性,艺术化不能牺牲核心功能。

可以瞅一眼我的 pyqart,很早就支持了。
不过没有时间做这个项目类似的支持动图和透明过滤功能。

学习了,赞!

赞。

牛逼,这个不错

我也测试过你的 pyqart,QArt 部分还可以,但是测试 Halftone 时发现马眼周围有些奇怪的边界,没法填充完整
![]( )
![]( )
所以最终还是用了 写的库,比较好改

支持中文吗

基于 sylnsfar/qrcode 开发的,原版不支持中文,所以不支持。我有空重写一下,不基于他的来做就可以了

有没有小程序码的美化库或者方案啊。

漂亮,star

已 star
为毛 fork 比 star 多 20 多倍 (滑稽

没有。但是小程序码也有普通二维码的形式,可以用普通二维码来转换

因为我也是 fork 原项目的,所以显示的是 fork 数量,哈哈

原来如此



这个奇怪的问题我抽空看一下,应该根据 spec 这部分并不是数据区。

但是有点久了记不太清了。。

回到顶部